【问题标题】:Golang reference to slice field in array of typesGolang 对类型数组中切片字段的引用
【发布时间】:2013-03-19 07:54:45
【问题描述】:

我是一名喜欢 Go 的 Python 程序员。经常让我绊倒的是引用的使用;我已经(大部分)掌握了它,但有时有些东西让我感到困惑,比如这个。

我有一个简单的类型('Fixture'):

type Fixture struct {
    Probabilities      *[]float64
}

如果我为这种类型的单个实例填充概率字段,一切都很好:

c := appengine.NewContext(r)
f := Fixture{}
p := []float64{}
p = append(p, 0.5)
p = append(p, 0.2)
p = append(p, 0.3)
f.Probabilities = &p
c.Infof("%v", *f.Probabilities)

2013/03/19 07:37:36 INFO: [0.5 0.2 0.3]

但是,如果我尝试为这些类型的数组填充此字段,代码会编译,但字段值始终为 nil:

c := appengine.NewContext(r)
fixtures := []Fixture{}
f := Fixture{}
fixtures = append(fixtures, f)
for _, f := range fixtures {
    p := []float64{}
    p = append(p, 0.5)
    p = append(p, 0.2)
    p = append(p, 0.3)
    f.Probabilities = &p
}
for _, f := range fixtures {
    // c.Infof("%v", *f.Probabilities) // causes error
    c.Infof("%v", f.Probabilities)
}

2013/03/19 07:37:41 INFO: <nil>

我想我不明白数组/切片是如何工作的,尤其是在引用方面。谁能指出我哪里出错了?

谢谢!

【问题讨论】:

  • 附注您使用指向切片的指针似乎没有意义。直接使用切片即可。
  • 1:您不必在此处使用指向切片的指针。切片是对实际数组的引用。 2:你的实际问题(如 jnml 和 PeterSo 在这里写的)是f in range 是一个副本和更改,不会更改切片元素。 3:为什么不做一个创建新Fixtures的函数呢?

标签: go


【解决方案1】:

在范围声明中

for _, f := range fixtures { ... }

f 是一个新声明的Fixture 类型的局部变量。它不是对任何事物的引用。所以在设置好它的值之后,必须把它放到fixtures切片中。

package main

import "fmt"

type Fixture struct {
        Probabilities *[]float64
}

func main() {
        fixtures := []Fixture{}
        f := Fixture{}
        fixtures = append(fixtures, f)
        for i, f := range fixtures {
                p := []float64{}
                p = append(p, 0.5)
                p = append(p, 0.2)
                p = append(p, 0.3)
                f.Probabilities = &p
                fixtures[i] = f
        }
        for _, f := range fixtures {
                fmt.Printf("%v", f.Probabilities)
        }
}

(也叫here


输出

&[0.5 0.2 0.3]

【讨论】:

  • 或者,制作一个指针切片[]*Fixture,以便该范围将复制指针,但它仍然指向原始切片元素。
【解决方案2】:

将元素值存储在切片中。例如,

package main

import "fmt"

type Fixture struct {
    Probabilities *[]float64
}

func main() {
    fixtures := make([]Fixture, 1)
    for i := range fixtures {
        p := []float64{0.5, 0.2, 0.3}
        fixtures[i] = Fixture{Probabilities: &p}
    }
    for _, f := range fixtures {
        fmt.Println(*f.Probabilities)
    }
}

输出:

[0.5 0.2 0.3]

【讨论】:

    猜你喜欢
    • 2014-09-19
    • 2014-08-08
    • 2017-05-12
    • 2013-10-23
    • 2014-08-05
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多