这些指针发生了什么?

时间:2016-04-25 18:51:30

标签: go

我写了一些奇怪的代码,但我不确定它为什么会起作用以及我可以从中学到什么。我有一个来自另一个结构的切片类型构建。我在切片类型上创建了一个函数来修改它自己。要做到这一点,我似乎不得不抛弃一点点。

我正在尝试学习Go中的指针并希望得到一些帮助。这是一个例子(http://play.golang.org/p/roU3MEeT3q):

var ClientNames = []string {"Client A", "Client B", "ClientC"}


type InvoiceSummaries []InvoiceSummary
type InvoiceSummary struct {
    Client string
    Amt    int
}

func (summaries *InvoiceSummaries) BuildFromAbove() {
    for _, name := range ClientNames {
         *summaries = append(*summaries, InvoiceSummary{name, 100})
    }
}

我的问题是:每个*的目的是什么?为什么我不使用任何&?

3 个答案:

答案 0 :(得分:1)

你必须使用指针作为接收器 - (summaries *InvoiceSummaries) - 因为否则参数是通过值传递的,有一个指针意味着你传递对该值的引用。如果不是那样的话,那么根本无法修改集合。

在方法体内部,您使用*,因为它是dereferncing运算符并返回地址处的值。 &符号(&)是相反的,它给出了值的地址。

答案 1 :(得分:1)

您的代码没有任何问题,但通常不会使用切片的地址。切片是一个小结构,gophers通常很乐意通过值传递。如果方法或函数正在创建新切片,则gopher很乐意再次按值返回新切片作为返回值。

当然,按值传递切片并不能保证在方法/函数返回时有关后备存储的任何内容保持不变。因此,它无法用作保证切片数据元素不变的方式。

答案 2 :(得分:1)

  

每个* *的目的是什么?

通过将方法接收器作为指针,您可以轻松更改对象的属性。我认为这是其中一个好处。下面的例子将证明这一点。

package main

import "fmt"

type someStruct struct {
    someVar int
}

func (s someStruct) changeVal1(newVal int) {
    s.someVar = newVal
}

func (s *someStruct) changeVal2(newVal int) {
    s.someVar = newVal
}

func main() {
    s := someStruct{0}
    fmt.Println(s) // {0}

    s.changeVal1(3)
    fmt.Println(s) // {0}

    s.changeVal2(4)
    fmt.Println(s) // {4}

    (&s).changeVal2(5)
    fmt.Println(s) // {5}
}
  

为什么我没有使用任何&?

指针方法接收器很特殊,它也可以从非指针结构对象中调用。 s.changeVal2(4)(&s).changeVal2(5)都是有效的&会影响someVar的价值。

示例http://play.golang.org/p/sxCnCD2D6d