微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我不能追加到golang中结构属性的切片?

我正在尝试将值附加到golang切片,如果在第一个方法调用它,代码就可以工作,但如果此方法调用一个方法,则代码似乎失败了.

示例(Test3是我最初尝试做的):

package main

import (
  "fmt"
)

// This works

type Test1 struct {
  all []int
}

func (c Test1) run() []int {
  for i := 0; i < 2; i++ {
    c.all = append(c.all,i)
  }
  return c.all
}

// This works

var gloabl_all []int

type Test2 struct {}

func (c Test2) run() []int {
  c.combo()
  return gloabl_all
}

func (c Test2) combo() {
  for i := 0; i < 2; i++ {
    gloabl_all = append(gloabl_all,i)
  }
}

// This doesn't

type Test3 struct {
  all []int
}

func (c Test3) run() []int {
  c.combo()
  return c.all
}

func (c Test3) combo() {
  for i := 0; i < 2; i++ {
    c.all = append(c.all,i)
    fmt.Println("Test3 step",i + 1,c.all)
  }
}

func main() {
  test1 := &Test1{}
  fmt.Println("Test1 final:",test1.run(),"\n")

  test2 := &Test2{}
  fmt.Println("Test2 final:",test2.run(),"\n")

  test3 := &Test3{}
  fmt.Println("Test3 final:",test3.run())
}

输出

Test1 final: [0 1] 

Test2 final: [0 1] 

Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: []

游乐场副本:https://play.golang.org/p/upEXINUvNu

任何帮助将不胜感激!

Go中的所有内容都按值传递.并且复制由传递的值组成.

Test3.combo()有值(非指针)接收器:

func (c Test3) run() []int {
  c.combo()
  return c.all
}

func (c Test3) combo() {
  for i := 0; i < 2; i++ {
    c.all = append(c.all,c.all)
  }
}

这意味着当从test3.run()调用Test3.combo()时,如c.combo(),副本由c(其类型为Test3)组成. combo()方法在副本上运行.它正确地将2个数字附加到Test3.all,但是当此方法返回时,将丢弃该副本.

因此,当Test3.run()返回c.all时,它返回一个空(nil)切片,因为附加了Test3.combo()的切片是一个副本的字段,并且已被丢弃.

解决方案:只需使用指针接收器:

func (c *Test3) combo() {
  for i := 0; i < 2; i++ {
    c.all = append(c.all,c.all)
  }
}

输出(在Go Playground上试试):

Test1 final: [0 1] 

Test2 final: [0 1] 

Test3 step 1 [0]
Test3 step 2 [0 1]
Test3 final: [0 1]

注意接收器中的星号*:func(c * Test3)combo().通过添加它,你使接收器成为一个指针,所以当调用combo()时,它只接收一个指向Test3类型值的指针,它将修改指向的值,Test3.run()具有的值,所以当combo()返回时,更改不会丢失.

原文地址:https://www.jb51.cc/go/186954.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐