为什么调用者在切片中看不到新数据?

huangapple go评论100阅读模式
英文:

Why isn't caller seeing new data in slice?

问题

在下面的代码中,为什么fmt.Println(len(people))两次都打印出0呢?正如在这里指出的https://stackoverflow.com/a/2441112/315445以及其他地方所提到的,切片是引用类型。为什么调用者(main函数)没有看到更新后的数据呢?

  1. package main
  2. import "fmt"
  3. type Person struct {
  4. name string
  5. age string
  6. }
  7. func main() {
  8. var people = make([]Person, 0)
  9. fmt.Println(len(people))
  10. getList(people)
  11. fmt.Println(len(people))
  12. }
  13. func getList(people []Person) {
  14. people = append(people, Person{"Foo", "1"})
  15. people = append(people, Person{"Bar", "2"})
  16. }

但是下面的代码可以正常工作。所以它实际上不是按引用传递吗?

  1. package main
  2. import "fmt"
  3. type Person struct {
  4. name string
  5. age string
  6. }
  7. func main() {
  8. var people = make([]Person, 0)
  9. fmt.Println(len(people))
  10. people = getList(people)
  11. fmt.Println(len(people))
  12. }
  13. func getList(people []Person) []Person {
  14. people = append(people, Person{"Foo", "1"})
  15. people = append(people, Person{"Bar", "2"})
  16. return people
  17. }
英文:

In the below code, why are both fmt.Println(len(people)) printing 0?
As pointed out here, https://stackoverflow.com/a/2441112/315445, and elsewhere, slice is reference type. Why isn't caller (main) seeing the updated data?

  1. package main
  2. import "fmt"
  3. type Person struct {
  4. name string
  5. age string
  6. }
  7. func main() {
  8. var people = make([]Person, 0)
  9. fmt.Println(len(people))
  10. getList(people)
  11. fmt.Println(len(people))
  12. }
  13. func getList(people []Person) {
  14. people = append(people, Person {"Foo", "1"})
  15. people = append(people, Person {"Bar", "2"})
  16. }

But this works. So its not actually a pass-by-reference?

  1. package main
  2. import "fmt"
  3. type Person struct {
  4. name string
  5. age string
  6. }
  7. func main() {
  8. var people = make([]Person, 0)
  9. fmt.Println(len(people))
  10. people = getList(people)
  11. fmt.Println(len(people))
  12. }
  13. func getList(people []Person) []Person {
  14. people = append(people, Person {"Foo", "1"})
  15. people = append(people, Person {"Bar", "2"})
  16. return people
  17. }

答案1

得分: 1

一个切片包含指向支持数组的指针、长度和容量。内置的append函数返回一个新的切片,具有新的长度和可能指向重新分配的支持数组的新指针。

切片是按值传递的。在getList函数中对切片的更改对调用者不可见。对支持数组的更改对调用者可见。

切片被称为引用类型,因为切片包含指向支持数组的指针。

英文:

A slice contains a pointer to the backing array, length and capacity. The append built-in returns a new slice with a new length and possibly a new pointer to a reallocated backing array.

Slices are passed by value. Changes to the slice in getList are not visible in the caller. Changes to the backing array are visible to the caller.

A slice is called a reference type because a slice contains a pointer to the backing array.

huangapple
  • 本文由 发表于 2016年4月26日 19:32:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/36863719.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定