一尘不染

为什么slice [] struct与[] builtin的行为不同?

go

切片是对基础数组的引用。这是有道理的,似乎可以在内置/原始类型上使用,但是为什么不能在结构上使用呢?我假设即使我更新了一个struct字段,引用/地址也仍然相同。

package main

import "fmt"

type My struct {
    Name string
}

func main() {
    x := []int{1}
    update2(x)
    fmt.Println(x[0])
    update(x)
    fmt.Println(x[0])
    my := My{Name: ""}
    update3([]My{my})
    // Why my[0].Name is not "many" ?
    fmt.Println(my)
}

func update(x []int) {
    x[0] = 999
    return
}
func update2(x []int) {
    x[0] = 1000
    return
}
func update3(x []My) {
    x[0].Name = "many"
    return
}

需要说明的是:我知道我可以在两种情况下都使用指针。我只是对为什么不更新结构感兴趣(与int不同)。


阅读 227

收藏
2020-07-02

共1个答案

一尘不染

调用时要做的update3是传递一个包含值副本的新数组,并立即丢弃该数组。这与您使用基元不同,因为您保留了数组。

这里有两种方法。

1) 使用指针数组而不是值数组:

您可以这样定义update3

func update3(x []*My) {
    x[0].Name = "many"
    return
}

并使用

update3([]*My{&my})

2) 在数组中写(以与处理原语相同的方式)

arr := make([]My,1)
arr[0] = My{Name: ""}
update3(arr)
2020-07-02