3 回答

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個(gè)贊
通常我們不知道給定的 append 調(diào)用是否會(huì)導(dǎo)致重新分配,因此我們不能假設(shè)原始切片與結(jié)果切片引用相同的數(shù)組,也不能假設(shè)它引用不同的數(shù)組。
要正確使用切片,重要的是要記住雖然底層數(shù)組的元素是間接的,但切片的指針、長(zhǎng)度和容量卻不是。
因此,通常將調(diào)用的結(jié)果分配給 append 到同一個(gè)切片變量:
array = append(array, ...)
總而言之,要獲得所需的結(jié)果,請(qǐng)始終記住將 append 函數(shù)分配給新的或相同的切片變量。
這是更正且有效的代碼:
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。
另一種解決方案是通過(guò)指針引用傳遞數(shù)組參數(shù):
func testFunction(array *[]float64) {
for i:=0; i<3; i++ {
*array = removeFrom(*array, 0)
}
fmt.Println(*array)
}

TA貢獻(xiàn)2080條經(jīng)驗(yàn) 獲得超4個(gè)贊
切片是復(fù)合類型。它有一個(gè)指向數(shù)據(jù)、長(zhǎng)度和容量的指針。當(dāng)您將它作為參數(shù)傳遞時(shí),您將傳遞這些值、指針、長(zhǎng)度和容量;它們總是副本。
在您的情況下,您在調(diào)用時(shí)修改切片中的數(shù)據(jù)removeFrom()
,您可以這樣做,因?yàn)槟褜⒅赶蛟紨?shù)據(jù)的指針的值復(fù)制到 func 中,但長(zhǎng)度和容量在該函數(shù)范圍之外保持不變那些不是指針。
因此,當(dāng)您再次打印它時(shí),main()
您會(huì)看到更改后的值,但它仍然使用原始長(zhǎng)度和容量,因?yàn)閷?duì)其他函數(shù)范圍內(nèi)的那些所做的任何更改實(shí)際上都是在這些值的副本上。

TA貢獻(xiàn)1856條經(jīng)驗(yàn) 獲得超11個(gè)贊
這是一篇關(guān)于切片的有用博客文章https://blog.golang.org/slices。它特別說(shuō)明了這一點(diǎn)。
重要的是要理解即使切片包含指針,它本身也是一個(gè)值。在幕后,它是一個(gè)包含指針和長(zhǎng)度的結(jié)構(gòu)值。它不是指向結(jié)構(gòu)的指針。
您看到的原因[40 50 50 50 50]
是因?yàn)槟牧饲衅械闹?,但您沒有更改切片本身(它是 cap 和 len)
- 3 回答
- 0 關(guān)注
- 162 瀏覽
添加回答
舉報(bào)