unsafe推荐博客:https://blog.csdn.net/hzwy23/article/details/60893765
按位运算符(>> << ~ & ^ | )及实例
^就是异或操作,相同为0,相异为1
双目运算符
fmt.Println(0&^0) //0
fmt.Println(0&^1) //0
fmt.Println(1&^0) //1
fmt.Println(1&^1) //0
1、如果右侧是0,则左侧数保持不变
2、如果右侧是1,则左侧数一定清零
3、功能同a&(^b)相同
4、如果左侧是变量,也等同于:
var a int
a &^= b
和它等价的c语言运算符表达式:
等价于c语言里的&=~
例如c语言的写法:
int a = 3;
a &= ~1;
各种运算符的优先级,详见菜鸟教程:http://www.runoob.com/go/go-operators.html
&a; 将给出变量的实际地址。
*a; 是一个指针变量
package main import "fmt" func main() { var a int = 4 var b int32 var c float32 var ptr *int /* 运算符实例 */ fmt.Printf("第 1 行 - a 变量类型为 = %T ", a ); fmt.Printf("第 2 行 - b 变量类型为 = %T ", b ); fmt.Printf("第 3 行 - c 变量类型为 = %T ", c ); /* & 和 * 运算符实例 */ ptr = &a /* 'ptr' 包含了 'a' 变量的地址 */ fmt.Printf("a 的值为 %d ", a); fmt.Printf("*ptr 为 %d ", *ptr); } 第 1 行 - a 变量类型为 = int 第 2 行 - b 变量类型为 = int32 第 3 行 - c 变量类型为 = float32 a 的值为 4 *ptr 为 4
switch var1 {
case val1:
...
case val2:
...
default:
...
}
select是Go中的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。
select随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的。
select { case communication clause : statement(s); case communication clause : statement(s); /* 你可以定义任意数量的 case */ default : /* 可选 */ statement(s); }
以下描述了 select 语句的语法:
- 每个case都必须是一个通信
- 所有channel表达式都会被求值
- 所有被发送的表达式都会被求值
- 如果任意某个通信可以进行,它就执行;其他被忽略。
- 如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。
否则:- 如果有default子句,则执行该语句。
- 如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。
package main import "fmt" func main() { var c1, c2, c3 chan int var i1, i2 int select { case i1 = <-c1: fmt.Printf("received ", i1, " from c1 ") case c2 <- i2: fmt.Printf("sent ", i2, " to c2 ") case i3, ok := (<-c3): // same as: i3, ok := <-c3 if ok { fmt.Printf("received ", i3, " from c3 ") } else { fmt.Printf("c3 is closed ") } default: fmt.Printf("no communication ") } }
以上代码执行结果为:
no communication
Channel是Go中的一个核心类型,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯(communication)。
它的操作符是箭头 <- 。
-
ch <- v // 发送值v到Channel ch中
-
v := <-ch // 从Channel ch中接收数据,并将数据赋值给v
(箭头的指向就是数据的流向)
就像 map 和 slice 数据类型一样, channel必须先创建再使用:
ch := make(chan int)
详见博客:https://blog.csdn.net/whatday/article/details/74453089
for循环
package main import "fmt" func main() { var b int = 15 var a int numbers := [6]int{1, 2, 3, 5} //numbers是个数组,6位,前4位是 1,2,3,5后面两位是0 /* for 循环 */ //第一种形式 for a := 0; a < 10; a++ { fmt.Printf("a 的值为: %d ", a) } for a < b { //第二种形式 a++ fmt.Printf("a 的值为: %d ", a) } for i,x:= range numbers { //第三种形式 ,range获取可迭代元素的索引和值 fmt.Printf("第 %d 位 x 的值 = %d ", i,x) } }
Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
package main import "fmt" func main() { /* 定义局部变量 */ var a int = 10 /* 循环 */ LOOP: for a < 20 { if a == 15 { /* 跳过迭代 */ a = a + 1 goto LOOP } fmt.Printf("a的值为 : %d ", a) a++ } }
函数
值传递 值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递 引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
普通函数 /* 函数返回两个数的最大值 */ func max(num1, num2 int) int { /* 声明局部变量 */ var result int if (num1 > num2) { result = num1 } else { result = num2 } return result } 匿名函数,匿名函数的优越性在于可以直接使用函数内的变量,不必申明 func getSequence() func() int { i:=0 return func() int { i+=1 return i } } func main(){ /* nextNumber 为一个函数,函数 i 为 0 */ nextNumber := getSequence() /* 调用 nextNumber 函数,i 变量自增 1 并返回 */ fmt.Println(nextNumber()) //1 fmt.Println(nextNumber()) //2 fmt.Println(nextNumber()) //3 /* 创建新的函数 nextNumber1,并查看结果 */ nextNumber1 := getSequence() fmt.Println(nextNumber1()) //1 fmt.Println(nextNumber1()) //2 }
方法 Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。就是给接受者赋予了一个新的方法 语法格式如下 func (variable_name variable_data_type) function_name() [return_type]{ /* 函数体*/ } package main import ( "fmt" ) /* 定义结构体 */ type Circle struct { radius float64 } func main() { var c1 Circle c1.radius = 10.00 fmt.Println("圆的面积 = ", c1.getArea()) } //该 method 属于 Circle 类型对象中的方法 func (c Circle) getArea() float64 { //c.radius 即为 Circle 类型对象中的属性 return 3.14 * c.radius * c.radius }
局部变量和全局变量
package main import "fmt" func main(){ var a int = 0 fmt.Println("for start") for a:=0; a < 10; a++ { fmt.Println(a) } fmt.Println("for end") fmt.Println(a) }
在 for 循环的 初始化initialize(a:=0) 中,此时 initialize 中的 a 与外层的 a 不是同一个变量,initialize 中的 a 为 for 循环中的局部变量,因此在执行完 for 循环后,输出 a 的值仍然为 0