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.