【问题标题】:Odd behavior of scopes [duplicate]范围的奇怪行为[重复]
【发布时间】:2020-03-24 19:30:38
【问题描述】:

考虑以下最小示例:

package main

import "fmt"

type runner interface {
    s1(int)
    s2(int)
}

type test struct {
    x1 []int
    x2 []int
}

func (t test) s1(v int) {
    t.x1 = append(t.x1, v)
    t.s2(v)
}

func (t test) s2(v int) {
    t.x2[v] = v
}


func main() {
    t := test{
        x1: make([]int, 0),
        x2: make([]int, 10)}

    for i := 0; i < 10; i++ {
        t.s1(i)
    }

    fmt.Println(t)
}

现在如果你运行它,你会得到这样的结果:

{[] [0 1 2 3 4 5 6 7 8 9]}

意味着x1 数组永远不会被填充。或者实际上,它是,但每次s1 函数退出时都会重置。 s2 可以很好地将项目放置在预定义的数组中。

有人知道这里到底发生了什么吗?是因为数组修改的范围吗?这似乎有点违反直觉。

附:我知道 x1 是一个切片,其中 x2 是一个实际的预定义数组。我自己的理论是,如果您使用“切片”,它们只能在特定范围内更改,而不能在其他任何地方更改。

【问题讨论】:

  • “值不会通过具有值接收器的方法修改”的变体(因此是重复的)。

标签: go


【解决方案1】:

值接收器复制类型并将其传递给函数。
只要让它成为指针,你就可以开始了:

func (t *test) s1(v int) {
    t.x1 = append(t.x1, v)
    t.s2(v)
}

输出:

&{[0 1 2 3 4 5 6 7 8 9] [0 1 2 3 4 5 6 7 8 9]}

代码:

package main

import "fmt"

type runner interface {
    s1(int)
    s2(int)
}

type test struct {
    x1 []int
    x2 []int
}

func (t *test) s1(v int) {
    t.x1 = append(t.x1, v)
    t.s2(v)
}

func (t test) s2(v int) {
    t.x2[v] = v
}

func main() {
    t := &test{
        x1: make([]int, 0),
        x2: make([]int, 10)}

    for i := 0; i < 10; i++ {
        t.s1(i)
    }

    fmt.Println(t)
}

【讨论】:

  • 酷,这很有趣。想知道在 go 中是否有关于这种特定类型的东西的读物,或者这种方法的推理是什么。不过它非常灵活。非常感谢您的回答
  • 阅读:1, 2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 2014-09-24
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多