使用反射附加到Go Lang 切片:了解機制
當嘗試使用反射將新元素附加到原始切片時,它是預期切片會隨之更新。但是,可能會觀察到這種情況不會發生,如以下程式碼所示:
import ( "fmt" "reflect" ) 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 的運作方式。與標準庫中的append函數類似,reflect.Append建立一個新的切片值而不是修改原始值。在上面的程式碼片段中,值被指派給新建立的切片,該切片取代了函數內的原始值,但不影響函數外的原始參數。
更正方法
要使用反射修改原始切片,應使用 Value.Set 方法。此方法允許更新原始值。 appendToSlice 函數的修正版本為:
func appendToSlice(arrPtr interface{}) { valuePtr := reflect.ValueOf(arrPtr) value := valuePtr.Elem() value.Set(reflect.Append(value, reflect.ValueOf(55))) fmt.Println(value.Len()) }
這確保原始切片按預期修改,並獲得以下輸出:
1 1
結論
使用反射修改切片時,必須考慮reflect.Append建立一個新切片而不是修改原來的。利用Value.Set方法,可以透過反射有效地修改原始切片,確保達到預期的結果。
以上是為什麼 Reflect.Append 沒有修改原廠的 Go Slice,如何修復?的詳細內容。更多資訊請關注PHP中文網其他相關文章!