go语言
基础
1.变量定义
局部变量
var name string = "小明";
name := "小明";
全局变量
age := 12;
var (
a int;
b bool;
)
赋值
a,b,c,d=1,2,3,"123";
2.常量
const (
a ,b = iota,iota //初始化值为0
)
1.1 类型总结
类型 | ⻓度 | 说明 |
---|---|---|
bool | 1 | true, false。不能把⾮零值当作 true。 |
byte | 1 | uint8 |
rune | 4 | int32。存储 Unicode Code Point。 |
int/uint | 与平台有关,在 AMD64/X86-64 平台是 64 位整数。 | |
int8/uint8 | 1 | -128 ~ 127; 0 ~ 255 |
int16/uint16 | 2 | -32768 ~ 32767; 0 ~ 65535 |
int32/uint32 | 4 | -21亿 ~ 21亿, 0 ~ 42亿 |
int64/uint64 | 8 | |
float32 | 4 | 精确到 7 个⼩数位 |
float64 | 8 | 精确到 15 个⼩数位 |
complex64 | 8 | |
complex128 | 16 | |
uintptr | ⾜够保存指针的 32 位或 64 位整数 | |
array | 值类型 如:[2]int | |
struct | 值类型 | |
string | 值类型 | |
slice | 引⽤类型 如: []int | |
map | 引⽤类型 | |
channel | 引⽤类型 | |
interface | 接⼝类型 | |
function | 函数类型 |
注意:定义的变量或者引用的包必须进行使用,否则会出现错误。
2.判断语句
var a int = 0;
b := 10;
if a < b {
fmt.Printf("a 小于 b");
}
与java类似
3.循环
共有三种用法
第一种与java相同
for a:=0;a<10;a++ {
fmt.Printf("a value is %d\n " ,a);
}
第二种根据条件来判断与while相同
var a int = 10;
var b int = 20;
for (a < b) {
fmt.Printf("a value is %d\n " ,a);
}
第三种
numbers := [6]int{1,2,3,5};
for i,x:= range numbers {
fmt.Println(x);
}
语言函数
在这里max中是函数名,括号内是参数值与参数类型,int 是指函数的返回值
func max(num1,num2 int) int{
println(value1,value2);
if (num1 > num2) {
return num1;
} else {
return num2;
}
}
go中的函数与java不一致的地方就是可以定义两个返回值
func swap(x,y string) (string,string) {
return x,y;
}
变量的作用域
- 局部变量
/*局部变量*/
var a,b,c int;
a = 10;
b = 20;
c = 30;
fmt.Println(a,b,c);
- 全局变量
var g int;
func main() {
a,b := 10,20;
g = a + b;
fmt.Printf("this is g value : %d\n",g);
}
语言数组
- 声明数组
var arrName[size] int;
- 初始化数组
var arr = [5]int{1,2,3,4,5};
var arr = [...]int{1,2,3,4,5,6};
GO的指针定义
var a int = 10;
//定义指针
var ip *int;
ip = &a;
fmt.Printf("a %x\n",&a);
fmt.Printf("ip %x\n",ip);
fmt.Printf("%d\n",*ip);
- 指针数组
package main;
import "fmt";
const MAX int = 3;
func main() {
//定义一个指针数组
var ptr [MAX]*int;
arr := []int{10,20,30};
for i := 0;i < MAX;i++ {
//赋值只能是地址
ptr[i] = &arr[i];
}
//循环数组
for x,y := range ptr {
//要获取值需要在y前面加*号
fmt.Println(x,*y);
}
}
- 指向指针的指针
var a int = 10;
var ptr *int;
var pptr **int;
ptr = &a;
pptr = &ptr;
fmt.Println("a的变量值为",a);
fmt.Printf("ptr 的变量值为 : %d \n",*ptr);
println("pptr的变量值:" ,**pptr)
- 指针作为函数传递
func main() {
a := 10;
b := 20;
fmt.Println("交换之前的a",a);
fmt.Println("交换之前的b",b);
swmp(&a,&b);
fmt.Println("交换之后的a",a);
fmt.Println("交换之后的b",b);
}
func swmp(x *int, y *int) {
var c int
c = *y;
*y = *x;
*x = c;
}
Go语言的结构体
- 定义结构体
package main;
import "fmt";
type Books struct {
title string;
author string;
subject string;
book_id int;
}
func main() {
//类似java中的构造器
fmt.Println(Books{"测试","结果 ","结构体",1});
//也可以采用key - value 的形式
fmt.Println(Books{title:"测试1",author:"测试结果",subject:"结构体",book_id:2});
}
- 结构体的使用
与java的类的概念很像,但是在定义时比java的要精简的很
import "fmt";
type Books struct {
title string;
author string;
subject string;
book_id int;
}
func main() {
var book1 Books;
var book2 Books;
book1.title = "jvm运行原理";
book1.author = "C从入门到精通";
book1.subject = "有你相看的书籍";
book1.book_id = 1;
//第二个
book2.title = "jvm运行原理";
book2.author = "C从入门到精通";
book2.subject = "有你相看的书籍";
book2.book_id = 2;
fmt.Printf("book1.title : %s\n ",book1.title);
fmt.Printf("book2.book_id : %d \n",book2.book_id);
}
- 作为参数进行传递
type Books struct {
title string;
author string;
subject string;
book_id int;
}
func main() {
var book1 Books;
var book2 Books;
book1.title = "jvm运行原理";
book1.author = "C从入门到精通";
book1.subject = "有你相看的书籍";
book1.book_id = 1;
//第二个
book2.title = "jvm运行原理";
book2.author = "C从入门到精通";
book2.subject = "有你相看的书籍";
book2.book_id = 2;
printBook(book1);
}
func printBook( book Books ) {
fmt.Printf( "Book title : %s\n", book.title);
fmt.Printf( "Book author : %s\n", book.author);
fmt.Printf( "Book subject : %s\n", book.subject);
fmt.Printf( "Book book_id : %d\n", book.book_id);
}
Go语言切片
使用makx来进行定义
make([]T, length, capacity)
package main;
import "fmt";
func main() {
var numbers = make([]int,3,5);
printSlice(numbers);
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x);
}
切片截取
func main() {
var numbers = []int{1,2,3,4,5,6,7,7,8,8,9};
printSlice(numbers);
fmt.Println(numbers[0:4]);
fmt.Println(numbers[4:]);
fmt.Println(numbers[:4]);
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x);
扩容
func main() {
//var numbers = []int{1,2,3,4,5,6,7,7,8,8,9};
var numbers [] int;
printSlice(numbers);
numbers = append(numbers,12);
printSlice(numbers);
numbers = append(numbers,33,22,11,42);
printSlice(numbers);
// 创建两倍容量
numbers1 := make([]int,len(numbers),(cap(numbers))*2);
copy(numbers1,numbers);
printSlice(numbers1);
numbers1 = append(numbers1,12,3,123,123,12,3);
printSlice(numbers1);
numbers1 = append(numbers1,12,3,123,123,12,3);
printSlice(numbers1);
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x);
}
范围range
package main;
import "fmt";
func main(){
var arr = []int{1,2,3};
vs := 0;
for _, v := range arr {
vs += v;
}
fmt.Println(vs);
kvs := map[string]string{"name":"qiao","b":"aaa"};
for k,v := range kvs {
fmt.Printf("k=%s,v=%s\n",k,v);
}
for i,j := range "go" {
fmt.Println(i,j);
}
}
MAP的定义与使用
package main;
import "fmt";
func main() {
//定义map
testMap := make(map[string]string);
testMap["name"] = "csdn";
testMap["age"] = "12";
for k,v := range testMap {
fmt.Printf("k=%s,v=%s\n",k,v);
}
captial,ok := testMap["name"];
if(ok) {
fmt.Println("存在",captial);
}else {
fmt.Println("不存在");
}
//删除
delete(testMap,"name");
for key := range testMap{
fmt.Println(testMap[key]);
}
}s
类型转换
语法 : type_name(value);
var a int = 13;
var b int = 3;
result := float32(a)/float32(b);
fmt.Println(int(result),"结果");
定义接口
package main
import (
"fmt"
)
type Phone interface {
call()
}
type NokiaPhone struct {
}
func (nokiaPhone NokiaPhone) call() {
fmt.Println("I am Nokia, I can call you!")
}
type IPhone struct {
}
func (iPhone IPhone) call() {
fmt.Println("I am iPhone, I can call you!")
}
func main() {
var phone Phone
phone = new(NokiaPhone)
phone.call()
phone = new(IPhone)
phone.call()
}
-- 带返回值的接口
注意在接口中,所有定义的属性都应该实现
定义错误方法
package main;
import (
"fmt"
);
//定义除法结构体
type DivideError struct {
dividee int;
divider int;
}
//实现错误接口
func (div *DivideError) Error() string {
strFormat := `
Cannot proceed,the divider is zero
dividee :%d
divider : 0
`
return fmt.Sprintf(strFormat,div.dividee);
}
func Divide(varDividee int,varDivider int) (result int,errMsg string) {
if varDivider == 0 {
eData := DivideError{
dividee : varDividee,
divider : varDivider,
}
errMsg = eData.Error();
return
}else {
return varDividee / varDivider,""
}
}
func main() {
result,errorMsg := Divide(10,0);
if errorMsg != "" {
fmt.Printf("errorMsg : %s",errorMsg);
}else {
fmt.Printf("value is of : %d",result);
}
}
go的csp模型
channel
c := make(chan int)
var send chan<- int = c // send-only
var recv <-chan int = c // receive-only
buffered channel
c := make(chan int , 3)
正常创建的channel,必须立刻有人接受,这样也是比较消耗性能的
创建buffered后,可以给他一个缓冲区,在达到一定数量后才进行
range
如果没有范围控制,在输出channel时,就会一直进行输出
理论基础
Communication Sequential Process (CSP) 通信顺序进程
我们通常都是通过共享内存来通信,而go是通过通信来同享内存
最后欢迎大家批评指正,您的建议就是我前进的动力。