golang 坑集

func main() {
	x := 1
	defer func(a int) { fmt.Println("a=", a) }(x)
	defer func() { fmt.Println("x=", x) }()
	x++
}

結果: x=2 a=1 golang

說明: defer 調用所需參數在 defer 語句執行時就被已計算好了 (拷貝傳遞),閉包內則是引用,defer執行順序FIFO 數組

數組和slice 閉包

數組是值類型 slice是引用類型, app

數組的建立  arr:=[...]int{1,2,3}   arr:=[3]int{}  arr:=new([10]int) (注意new返回的是[10]int的指針類) 性能

slice的建立  slice:=[]int{1,2,3} slice:=arr[n:m]( n <= x  < m) slice:=make([]int,len,[cap]) (cap default=len) spa

每一個slice指向了一個底層數組,對slice的更新會反映到這個底層數組上,cap=slice在數組的start_index到數組的end_index 指針

reslice  slice1:=slice2[n:m] 在slice進行reslice時若是n,m超過了cap 不會引起底層數組的重分配 ,而會panic: runtime error: index out of range code

append(s1,1,2,3) 能夠引起底層數組重分配 增長一個cap 對象

copy(dst,src)  len=min(len(dst),len(src)) 繼承

map

d := map[*int]struct{ x, y float64 } { &10: { 1.0, 2.0 } }


struct 和數組同樣 也是 值類型

type s1 struct {
	s2 struct {
		a int
	}
}
func main() {
	m := map[int]struct{ a int }{1: {1}}//正確
	fmt.Println(m)
	
	s := s1{{1}}//異常 missing type in composite literal
	fmt.Println(s)
}
 匿名struct能夠做爲map的value並且賦值方便,而匿名struct做爲struct的成員則在初始化時 須要帶上struct的名字才行,成員變量 匿名struct 就不方便了。

struct拷貝複製

u := User{ 100, "Tom" }
var u2 *User = new(User)
*u2 = u


匿名成員 (組合優於繼承)

type D1 struct {
	x int
}
type Data struct {
	D1
	x int
}

func main() {
	d := Data{D1{10}, 20}
	d.x = 200
	d.D1.x = 100
	fmt.Println(d)
}


接口類型推斷

if o,ok:=i.(User);ok{ o.xxx } switch o:=i.(type){ case User: xxx case Man: xxx }

將對象賦值給接口變量時,會發發生值拷貝行爲

u := User{ 1, "Tom" }
i := Tester(u)//強制轉換 賦值發生的是copy動做
//在golang裏要千萬注意 = 這個賦值動做 都是copy動做,若是copy的對象是個指針的話性能會比較好
u.Id = 100 // 顯式修改的原對象
u.Name = "Jack"
fmt.Println(u, i) // 雖然接⼝口內的複製品未受到影響
相關文章
相關標籤/搜索