首頁 > 後端開發 > Golang > 為什麼Reflection的`Append`函數不更新原來的Go Slice?

為什麼Reflection的`Append`函數不更新原來的Go Slice?

Barbara Streisand
發布: 2024-11-26 01:10:12
原創
630 人瀏覽過

Why Doesn't Reflection's `Append` Function Update the Original Go Slice?

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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板