Go 反射中的附加函數
在 Go 中,使用反射將元素附加到切片似乎不會更新原始切片。下面的程式碼說明了這一點:
func appendToSlice(arrPtr interface{}) { valuePtr := reflect.ValueOf(arrPtr) value := valuePtr.Elem() value = reflect.Append(value, reflect.ValueOf(55)) fmt.Println(value.Len()) // prints 1 } func main() { arr := []int{} appendToSlice(&arr) fmt.Println(len(arr)) // prints 0 }
為什麼不行?
根本原因在於reflect.Append的行為。與傳統的追加函數一樣,它會傳回一個新的切片值。在這種情況下,指派給 value 變數的值將會被替換為這個新切片,從而有效地建立副本。
為了說明這一點,讓我們修改範例以突出顯示發生的情況:
func appendToSlice(arrPtr *[]int) { value := *arrPtr value = append(value, 55) fmt.Println(len(value)) } func main() { arr := []int{} appendToSlice(&arr) fmt.Println(len(arr)) }
即使我們沒有使用,修改後的程式碼也會產生相同的輸出
解
要使用反射正確追加到切片,我們需要使用Value.Set方法修改原始值:
func appendToSlice(arrPtr interface{}) { valuePtr := reflect.ValueOf(arrPtr) value := valuePtr.Elem() value.Set(reflect.Append(value, reflect.ValueOf(55))) fmt.Println(value.Len()) }
此方法將新建立的切片傳遞給 value.Set,更新原始切片。
以上是為什麼Reflection的`Append`函數不更新原來的Go Slice?的詳細內容。更多資訊請關注PHP中文網其他相關文章!