首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我不能使用引用将值附加到结构体的切片中?

为什么我不能使用引用将值附加到结构体的切片中?
EN

Stack Overflow用户
提问于 2019-12-01 10:59:41
回答 3查看 681关注 0票数 0

我假设切片是通过引用传递的,但这似乎对值有效,但对数组本身无效。例如,如果我有这样的结构:

代码语言:javascript
运行
复制
    l := Line{
        Points: []Point{
            Point{3, 4},
        },
    }

我可以定义一个变量,它会传递一个对结构切片的引用

代码语言:javascript
运行
复制
slice := l.Points

然后,如果我修改它,变量引用的原始结构将反映这些修改。

代码语言:javascript
运行
复制
slice[0].X = 1000
fmt.Printf(
    "This value %d is the same as this %d", 
    slice[0].X, 
    l.Points[0].X,
)

这与数组的行为不同,我假设数组是通过值传递的。因此,例如,如果我使用数组定义了前面的代码:

代码语言:javascript
运行
复制
l := Line{
    Points: [1]Point{
        Point{3, 4},
    },
}
arr := l.Points
arr[0].X = 1000
fmt.Println(arr.[0].X != s.Points[0].X) // equals true, original struct is untouched

那么,l结构就不会被修改。

现在,如果我想修改切片本身,我显然不能这样做:

代码语言:javascript
运行
复制
slice = append(slice, Point{99, 100})

因为这只会重新定义切片变量,从而丢失原始引用。我知道我可以简单地这样做:

代码语言:javascript
运行
复制
l.Points = append(l.Points, Point{99, 100})

但是,在某些情况下,使用另一个变量会更方便,而不必键入整个变量。

我试过这个:

代码语言:javascript
运行
复制
*slice = append(*slice, Point{99, 100})

但它不起作用,因为我试图取消引用显然不是指针的对象。

我最终尝试了一下:

代码语言:javascript
运行
复制
slice := &l.Points

*slice = append(l.Points, Point{99, 100})

它起作用了,但我不确定发生了什么。为什么slice的值没有被覆盖?append在这里是如何工作的?

EN

Stack Overflow用户

发布于 2019-12-01 11:33:14

Append返回一个新的切片,它可能会修改初始切片的原始后备数组。原始切片仍将指向原始支持数组,而不是新的支持数组(它可能在内存中的相同位置,也可能不在内存中的相同位置)

例如(playground)

代码语言:javascript
运行
复制
slice := []int{1,2,3}
fmt.Println(len(slice))
// Output: 3
newSlice := append(slice, 4)
fmt.Println(len(newSlice))
// Output: 4
fmt.Println(len(slice))
// Output: 3 

虽然片可以被描述为“指向数组的胖指针”,但它不是指针,因此您不能取消对它的引用,这就是为什么会出现错误的原因。

通过创建一个指向切片的指针,并像上面那样使用append,您可以将指针所指向的切片设置为由append返回的“新”切片。

有关更多信息,请查看Go Slice Usage And Internals

票数 2
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59122177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档