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 关注
- 138 浏览
添加回答
举报