type Student struct { Name string Age int}func main() { data := make([]*Student, 0) src := []Student{ Student{Name: "allen", Age: 30}, Student{Name: "tom", Age: 33}, } for _, m := range src { data = append(data, &m) // notice point!!! } for _, s := range data { fmt.Println(*s) }}為什么這段代碼在 Go 中可以運行?輸出與預期相反,如下所示。{tom 33}{tom 33}代替{allen 30}{tom 33}我發現的一個解釋是m是一個固定指針,因此每次append(data,&m)只附加 的地址m,該地址在迭代期間保持不變。然而,根據這個解釋,m似乎是 of *Student,所以&m是 of **Student,但是如何將一個 value( &m)**Student追加到一個數組中呢[]*Student?
3 回答

溫溫醬
TA貢獻1752條經驗 獲得超4個贊
當范圍覆蓋切片時,每次迭代都會返回兩個值。第一個是索引,第二個是該索引處元素的副本。
因此,它具有您正在迭代的數組/切片的值。
在你的情況下,該值是一個Student
結構

慕田峪7331174
TA貢獻1828條經驗 獲得超13個贊
實際上這與 Go 中一切都是按值傳遞這一事實有關。
m := range src
m始終是相同的引用,并且其值會更新。查看它的一個簡單方法是打印地址
for _, m := range src {
? ? // ---
? ? p := &m
? ? fmt.Printf("%p\n", p)
? ? // ---
? ? data = append(data, &m) // notice point!!!
}

慕的地10843
TA貢獻1785條經驗 獲得超8個贊
首先,你可以通過內省來找出真相m
。另外,您可以在循環之前聲明它 ( var m ...
) 作為實驗。
現在,你寫“我發現 m 是一個固定指針”。首先,我不確定你所說的“固定指針”是什么意思,我也不認為你是這樣的。固定(或常量)的是 的地址m
。結論是“因此每次都append(data,&m)
只是附加地址m
”,這正是發生的情況。然而,你的假設“m
似乎是*Student
”是有缺陷的,而是m
類型Student
,就這么簡單。
- 3 回答
- 0 關注
- 214 瀏覽
添加回答
舉報
0/150
提交
取消