Golang:make,slice,appendの注意点

2078 ワード

appendを使用してsliceに要素が遭遇したピットを追加し、ここでまとめます.一、詳細1
urls := make(map[string]string, 3) 
urls["baidu"] = "www.baidu.com"
urls["google"] = "www.google.com"
urls["csdn"] = "www.csdn.net"
names := make([]string, len(urls))
for key, _ := range urls {
    names = append(names, key)
    }
fmt.Println(names,len(names))

出力結果[csdn baidu google]6の前にいくつかのスペースが追加され、長さは6で、予想された結果と一致しない修正コード
names := make([]string, 0)
for key, _ := range urls {
    names = append(names, key)
}
fmt.Println(names,len(names))

または
var names []string
for key, _ := range urls {
    names = append(names, key)
}
fmt.Println(names,len(names))

出力結果[baidu google csdn]3まとめ:appendはどうしてもsliceの末尾からデータを追加しますが、元のsliceは3つの長さしかありません.今ではappendごとにメモリ2、詳細2を再割り当てします.
s1 := []int{1, 2, 3}
s2 := []int{4, 5}
s1 = append(s1, s2)
fmt.Println(s1)

プログラムエラー:cannot uses 2(type[]int)as type int in appendが次のように変更されました.
s1 := []int{1, 2, 3}
s2 := []int{4, 5}
s1 = append(s1, s2...)
fmt.Println(s1)

出力結果:[12 3 4 5]まとめ:appendスライス時に漏れないように'...'三、詳細3 newとmakeの違い:newはメモリのみを割り当て、メモリを初期化せず、ゼロにするだけです.new(T)は、Tタイプの新しいアイテムであり、ゼロに設定されたストレージを割り当て、そのアドレスを返します.Tタイプの値、すなわち、新しい割り当てのタイプがTであるポインタを返します.このポインタが指す内容の値はゼロ(zero value)であり、ポインタがゼロではないことに注意してください.たとえば、boolタイプの場合、ゼロ値はfalse、intのゼロ値は0、stringのゼロ値は空の文字列です.makeはslice、map、channelの初期化に使用され、ゼロではなく初期化された(ゼロではなく)を返します.タイプはTではなくTの値です.この3つのタイプが異なるのは、使用前に初期化する必要があるデータ構造であるためです.たとえば、sliceはデータを指す3元記述子です.(配列内)のポインタ、長さ、容量、これらの項目が初期化される前に、sliceはnilです.slice、map、channelの場合、makeはこれらの内部データ構造を初期化し、使用可能な値を用意します.
p := new([]int) //p == nil; with len and cap 0,    slice      ,     nil slice   
fmt.Println(p)

v := make([]int, 10, 50) // v is initialed with len 10, cap 50
fmt.Println(v)

出力結果:&[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
new1 := new([2]int)
fmt.Println(new1)
new1[0] = 1
new1[1] = 2
fmt.Println(new1)

出力結果:&[00]&[12]