初級(jí)
1、不允許左大括號(hào)單獨(dú)一行
2、不允許出現(xiàn)未使用的變量
3、不允許出現(xiàn)未使用的import
解決方法:使用_作為引入包別名
package main
import (
_ "fmt" // 指定別名為`_`
"log"
"time"
)
var _ = log.Println // 變量名為`_`
func main() {
_ = time.Now
}
4秀仲、短的變量聲明(Short Variable Declarations)只能在函數(shù)內(nèi)部使用
package main
// myvar := 1 // error
var myvar = 1 // ok
func main() {
}
5、不能使用短變量聲明(Short Variable Declarations)重復(fù)聲明
6壶笼、不能使用短變量聲明(Short Variable Declarations)這種方式來(lái)設(shè)置字段值
package main
func main() {
one := 0
// one := 1 //error: Redeclaring Variables Using Short Variable Declarations
// data.result, err := work() //error:Can't Use Short Variable Declarations to Set Field Values
data.result, err = work() //ok
}
8神僵、不能使用nil初始化一個(gè)未指定類型的變量
// var x = nil //error
var x interface{} = nil // OK
_ = x
9、不能直接使用nil值的Slice和Map
10覆劈、map使用make分配內(nèi)存時(shí)可指定capicity保礼,但是不能對(duì)map使用cap函數(shù)
11沛励、字符串不允許使用nil值
在golang中,nil只能賦值給指針炮障、channel目派、func、interface胁赢、map或slice類型的變量企蹭。
var x string = nil //error
if x == nil { //error
x = "default"
}
//var x string //defaults to "" (zero value)
if x == "" {
x = "default"
}
12、數(shù)組用于函數(shù)傳參時(shí)是值復(fù)制
注意:方法或函數(shù)調(diào)用時(shí)智末,傳入?yún)?shù)都是值復(fù)制(跟賦值一致)谅摄,除非是map、slice系馆、channel送漠、指針類型這些特殊類型是引用傳遞。
x := [3]int{1,2,3}
// 數(shù)組在函數(shù)中傳參是值復(fù)制
func(arr [3]int) {
arr[0] = 7
fmt.Println(arr) //prints [7 2 3]
}(x)
fmt.Println(x) //prints [1 2 3] (not ok if you need [7 2 3])
// 使用數(shù)組指針實(shí)現(xiàn)引用傳參
func(arr *[3]int) {
(*arr)[0] = 7
fmt.Println(arr) //prints &[7 2 3]
}(&x)
fmt.Println(x) //prints [7 2 3]
13由蘑、range關(guān)鍵字返回是鍵值對(duì)闽寡,而不是值
x := []string{"a","b","c"}
// for v := range x {
// fmt.Println(v) //prints 0, 1, 2
// }
for _, v := range x {
fmt.Println(v) //prints a, b, c
}
14、Slice和Array是一維的
Go表面上看起來(lái)像多維的尼酿,實(shí)際上只是一維的爷狈。但可以使用原始的一維數(shù)組、一維的切片來(lái)實(shí)現(xiàn)多維裳擎。
15淆院、從不存在key的map中取值時(shí),返回的總是”0值”
x := map[string] string {"one":"1", "two":"2"}
if _,ok := x["two"]; !ok { // 判斷是否存在句惯,x[key]始終有返回值
}
16、字符串是不可變
x := "text"
// x[0] = 'T' // error
xtytes := []byte(x)
xbytes[0] = 'T' // ok
fmt.Println(string(xbytes)) //prints Text
17支救、字符串與[]byte之間的轉(zhuǎn)換是復(fù)制(有內(nèi)存損耗)抢野,可以用map[string] []byte建立字符串與[]byte之間映射,也可range來(lái)避免內(nèi)存分配來(lái)提高性能
//[]byte:
for i,v := range []byte(str) {
}
21各墨、在Slice指孤、Array、Map的多行書寫最后的逗號(hào)不可省略
x := []int{
1,
// 2 //error
3, // ok
}
y := []int {1, 2, 3,} // ok
z := []int {1, 2, 3} // 單行書寫贬堵,最后一個(gè)元素的逗號(hào)可省略
24恃轩、使用for range迭代map時(shí)每次迭代的順序可能不一樣,因?yàn)閙ap的迭代是隨機(jī)的黎做。
25叉跛、switch的case默認(rèn)匹配規(guī)則不同于其它語(yǔ)言的是,匹配case條件后默認(rèn)退出蒸殿,除非使用fallthrough繼續(xù)匹配筷厘;而其它語(yǔ)言是默認(rèn)繼續(xù)匹配鸣峭,除非使用break退出匹配。
31酥艳、對(duì)于無(wú)緩存區(qū)的channel摊溶,寫入channel的goroutine會(huì)阻塞直到被讀取,讀取channel的goroutine會(huì)阻塞直到有數(shù)據(jù)寫入充石。
32莫换、從一個(gè)closed狀態(tài)的channel讀取數(shù)據(jù)是安全的,可通過(guò)返回狀態(tài)(第二個(gè)返回參數(shù))判斷是否關(guān)閉骤铃;而向一個(gè)closed狀態(tài)的channel寫數(shù)據(jù)會(huì)導(dǎo)致panic拉岁。
33、向一個(gè)nil值(未用make分配空間)的channel發(fā)送或讀取數(shù)據(jù)劲厌,會(huì)導(dǎo)致永遠(yuǎn)阻塞膛薛。
package main
import (
"fmt"
"time"
)
func main() {
var ch chan int
for i := 0; i < 3; i++ {
go func(idx int) {
ch <- (idx + 1) * 2
}(i)
}
//get first result
fmt.Println("result:",<-ch)
//do other work
time.Sleep(2 * time.Second)
}