a := 1.0 - 1.0 fmt.Println("Hello, ", 9.0/a) // Hello, +Inf
对于整数和浮点数,可使用一元运算符 ++(递增)和 --(递减),但只能用于后缀。i++
带有 ++ 和 -- 的只能做为语句,而非表达式,所以 n = i++ 这种写法是无效的,其它像 f(i++) 或者 a[i]=b[i++] 这些能够用于 C、C++ 和 Java 中的写法在 Go 中也是不容许的.sql
在运算时 溢出 不会产生错误,Go 会简单地将超出位数抛弃。若是你须要范围无限大的整数或者有理数(意味着只被限制于计算机内存),你可使用标准库中的 big 包,该包提供了相似 big.Int 和 big.Rat 这样的类型。数组
%取模运算符的符号和被取模数的符号老是一致的,所以-5%3和-5%-3结果都是-2.闭包
i := 4 if i < 0 { fmt.Println("<0") } else if i == 0 { fmt.Println("=0") } else { fmt.Println(">0") }
if i, j := 0, 0; i <= 0 { fmt.Println(i, j) }
i, j只在if-else中有效,若是以前有i,j定义,则会覆盖oop
i := 7 switch i { case 0: fmt.Println(0) case 1: fmt.Println(1) case 2: fallthrough // 向下执行 case 3: fmt.Println(3) case 4, 5, 6: fmt.Println("4,5,6") default: fmt.Println("default") }
左花括号{必须与switch处于同一行;编码
条件表达式不限制为常量或者整数;指针
str := "a" switch str { case "a": fmt.Println("a") case "b": fmt.Println("b") }
单个case中,能够出现多个结果选项;code
case 4,5,6对象
与C语言等规则相反,Go语言不须要用break来明确退出一个case;默认退出索引
只有在case中明确添加fallthrough关键字,才会继续执行紧跟的下一个case,fallthrough再也不判断条件内存
能够不设定switch以后的条件表达式,在此种状况下,整个switch结构与多个if...else...的逻辑做用等同。
i := 0 switch { case 0 <= i && i <= 3: fmt.Println("0~3") case i > 3: fmt.Println(">3") }
带初始化语句
switch i, j := 9, 10; { case i == 1 && j == 10: fmt.Println("no") case i == 9 && j == 10: fmt.Println("yes") }
fallthrough示例
i := 0 switch i { case 0: fmt.Print("0 ") fallthrough case 1: fmt.Print("1") }
输出:0 1
switch 与类型判断:(database.sql/convert.go:convertAssign())
var src interface{} src = "123" switch s := src.(type) { case string: fmt.Printf("1:type:%T, value:%v\n", s, s) fmt.Println(strconv.ParseInt(s, 10, 64)) default: fmt.Printf("2:type:%T, value:%v", s, s) }
for i, n := 0, 10; i < n; i++ { fmt.Printf("%d\t", i) }
for i, n := 0, 10; ; i++ { fmt.Printf("%d\t", i) if i >= n { break } } loop: for i := 0; ; i++ { fmt.Printf("for1 :%d ", i) for j := 0; j <= i; j++ { if i == 1 && j == 1 { break loop } } }
for { }
for i < 10 { }
for i, v := range "汉字\x80" { fmt.Printf("character %#U starts at byte position %d\n", v, i) }
输出:
character U+6C49 '汉' starts at byte position 0 character U+5B57 '字' starts at byte position 3 character U+FFFD '�' starts at byte position 6
错误的编码(上例中的\x80)会占用一个字节,使用U+FFFD来代替
注意变量i第二次是3,而不是1
当for i:=range “sss”时,i表明的是下标。
for i, j := 0, 5; i < j; i, j = i+1, j-1 { fmt.Println(i, j) }
当使用下面的方式修改数组时: items := [...]int{10, 20, 30, 40, 50} for _, item := range items { item *= 2 } fmt.Println(items)
items的元素没有被修改。由于item是元素的拷贝而不是指针。 使用下面的方式可修改: items := [...]int{10, 20, 30, 40, 50} for i, _ := range items { items[i] *= 2 }
- for中变量的做用域 for i := 0; i < 3; i++ { for i := 0; i < 3; i++ { fmt.Println(i) } }
内层for也声明了i,这说明这个i屏蔽了外层的i,因此最后输出的是9个数。
var x = []int{5, 12, 32} // 使用值和索引 for i, v := range x { fmt.Println(i, "=>", v) } // 只使用索引 for v := range x { fmt.Println(v) // v是索引,0-3 } // 只使用值 for _, v := range x { fmt.Println(v) } // 不使用循环中的值 for _ = range x { fmt.Println(80) } // 不使用循环中的值,须要1.4之后版本 for range x { fmt.Println(90) }
range会复制对象
a := [3]int{0, 1, 2} // Q: range时内存中是否是有一个原数组和一个拷贝的数组 for i, v := range a { if i == 0 { a[1], a[2] = 999, 999 // 修改原数组 fmt.Printf("%v, %p \n", a, &a) } a[i] = v + 100 // 此时v是range以前原数组复制的值 fmt.Printf("%v, %p \n", a, &a) } fmt.Printf("%v, %p \n", a, &a)
输出:
[0 999 999], 0x20819e020 [100 999 999], 0x20819e020 [100 101 999], 0x20819e020 [100 101 102], 0x20819e020 [100 101 102], 0x20819e020
i和v的值在range时就被拷贝了,而引用类型不会复制底层数据:
s := []int{1, 2, 3, 4, 5} for i, v := range s { // 复制 struct slice {pointer, len, cap} if i == 0 { s = s[:3] // 对slice的修改不会影响range,修改的是range外的s s[2] = 100 // 对底层数据的修改,这里的s也是range外的 } fmt.Println(i, v) } fmt.Println(s)
输出:
0 1 1 2 2 100 3 4 4 5 [1 2 100]
另外两种引用类型 map, channel 是指针包装,而不像 slice 是 struct。
arr := []int{12, 34, 56} for _, v := range arr { go func() { fmt.Println(v) }() } time.Sleep(5 * time.Second)
上面输出都是56.缘由不明。
使用下面的语句能够达到遍历的目的:
arr := []int{12, 34, 56} for _, v := range arr { go func(v int) { fmt.Println(v) }(v) } time.Sleep(5 * time.Second)
func myfunc() { i := 0 HERE: fmt.Println(i) i++ if i < 10 { goto HERE } }
若是您必须使用 goto,应当只使用正序的标签(标签位于 goto 语句以后),但注意标签和 goto 语句之间不能出现定义新变量的语句,不然会致使编译失败。
// compile error goto2.go:8: goto TARGET jumps over declaration of b at goto2.go:8 package main import "fmt" func main() { a := 1 goto TARGET // compile error b := 9 TARGET: b += a fmt.Printf("a is %v *** b is %v", a, b) }
break可用于 for, switch, select, 而 continue 只能用于 for.