了解切片索引语义



问题的答案可能是"围棋就是这样的"但我想了解以下行为背后的原因,即对值类型的切片进行索引:

package main
import (
"fmt"
)
type S struct {
Data string
}
func main() {
s := []S{
{"first"},
{"second"},
{"third"},
}

// # 1
// This does not modify "s"
first := s[0]
first.Data = "something else"
fmt.Println(s)

// # 2
// ...but this does?
s[0].Data = "woah"
fmt.Println(s)

// # 3
// ...and this makes sense but feels inconsistent with the previous block
second := &s[1]
second.Data = "this makes sense"
fmt.Println(s)
}

我的问题是,既然var element S = s[0]编译了,但var element *S = s[0]不编译,为什么#2更新切片?

(在操场上运行(

first := s[0]创建s[0]的副本并分配给first,其类型为S

s[0].Data = "woah"是直接分配,非常简单。

second := &s[1]指针分配给s[1]second,其类型为*S。所以second.Data修改s[1].Data是因为它是一个指针。请注意,Go对成员访问和指针访问都使用点(在C中,这将是->运算符(。

写和理解这一点的等效方法是:

var first S
first = s[0]
var second *S
second = &s[1]

最新更新