3 回答

TA貢獻1810條經驗 獲得超4個贊
通常我們不知道給定的 append 調用是否會導致重新分配,因此我們不能假設原始切片與結果切片引用相同的數組,也不能假設它引用不同的數組。
要正確使用切片,重要的是要記住雖然底層數組的元素是間接的,但切片的指針、長度和容量卻不是。
因此,通常將調用的結果分配給 append 到同一個切片變量:
array = append(array, ...)
總而言之,要獲得所需的結果,請始終記住將 append 函數分配給新的或相同的切片變量。
這是更正且有效的代碼:
package main
import (
"fmt"
)
type testStruct struct {
testArray []float64
}
var test = testStruct {
testArray: []float64{10,20,30,40,50},
}
func main() {
fmt.Println(test.testArray)
a := testFunction(test.testArray)
fmt.Println(a)
}
func testFunction(array []float64)[]float64 {
for i:=0; i<3; i++ {
array = removeFrom(array, 0)
}
fmt.Println(array)
return array
}
func removeFrom(array []float64, index int) []float64 {
return append(array[:index], array[index+1:]...)
}
檢查它的工作代碼Go Playground。
另一種解決方案是通過指針引用傳遞數組參數:
func testFunction(array *[]float64) {
for i:=0; i<3; i++ {
*array = removeFrom(*array, 0)
}
fmt.Println(*array)
}

TA貢獻2080條經驗 獲得超4個贊
切片是復合類型。它有一個指向數據、長度和容量的指針。當您將它作為參數傳遞時,您將傳遞這些值、指針、長度和容量;它們總是副本。
在您的情況下,您在調用時修改切片中的數據removeFrom()
,您可以這樣做,因為您已將指向原始數據的指針的值復制到 func 中,但長度和容量在該函數范圍之外保持不變那些不是指針。
因此,當您再次打印它時,main()
您會看到更改后的值,但它仍然使用原始長度和容量,因為對其他函數范圍內的那些所做的任何更改實際上都是在這些值的副本上。

TA貢獻1856條經驗 獲得超11個贊
這是一篇關于切片的有用博客文章https://blog.golang.org/slices。它特別說明了這一點。
重要的是要理解即使切片包含指針,它本身也是一個值。在幕后,它是一個包含指針和長度的結構值。它不是指向結構的指針。
您看到的原因[40 50 50 50 50]
是因為您更改了切片中的值,但您沒有更改切片本身(它是 cap 和 len)
- 3 回答
- 0 關注
- 176 瀏覽
添加回答
舉報