这些指针是怎么回事?

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

What's happening with these pointers?

问题

我写了一些奇怪的代码,但我不确定它为什么能工作以及我能从中学到什么。我有一个由另一个结构体构建的切片类型。我在切片类型上创建了一个函数来修改自身。为了做到这一点,我似乎不得不频繁使用 *。

我正在尝试学习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})
    }
}

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

英文:

I wrote some odd code, but I'm not sure why it works and what I can learn from it. I have a slice type build from another struct. I made a function on the slice type to modify itself. To do this, I seem to have to throw around *'s a little much.

I'm trying to learn about pointers in Go and would like a little help. Here's an example (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})
    }
}

My question is: What is the purpose for each of these * and why am I not using any &?

答案1

得分: 1

你必须为接收器使用指针 - (summaries *InvoiceSummaries) - 因为否则参数是按值传递的,使用指针意味着你传递的是值的引用。如果没有指针,你将无法修改集合。

在方法体内部,你需要使用*,因为它是解引用运算符,返回地址处的值。而&则相反,它给出一个值的地址。

英文:

You have to use a pointer for the receiver - (summaries *InvoiceSummaries) - because otherwise the argument is passed by value, having a pointer means you pass a reference to the value instead. If not for that, then you couldn't modify the collection at all.

Inside of the methods body you have use * because it is the dereferncing operator and returns the value at the address. Ampersand (&) is the opposite, it gives the address of a value.

答案2

得分: 1

你的代码没有问题,但通常不会使用地址来引用切片。切片是一个小的结构体,Go语言开发者通常很乐意通过值传递切片。如果一个方法或函数创建了一个新的切片,开发者也很乐意将新的切片再次通过值返回作为返回值。

当然,通过值传递切片并不能保证在方法或函数返回时底层存储保持不变。因此,它不能用作确保切片的数据元素没有发生变化的方法。

英文:

Nothing wrong with your code but normally addresses to slices aren't used. A slice is a small struct that gophers are normally happy to pass by value. If a method or function is creating a new slice, the gopher is happy to return the new slice, by value again, as the return value.

Of course passing a slice by value doesn't guarantee anything about the backing store remaining unchanged when the method/function returns. So it can't be used as a way of guaranteeing the data elements of the slice haven't mutated.

答案3

得分: 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

英文:

> What is the purpose for each of these * ?

By making the method receiver as pointer, you could easily change the property of the object. I think that's one of the benefit. This example below will prove it.

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}
}

> and why am I not using any &?

Pointer method receiver is quite special, it can also be called from non-pointer struct object. Both of s.changeVal2(4) and (&s).changeVal2(5) are valid & will affect the value of someVar.

Example http://play.golang.org/p/sxCnCD2D6d

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

发表评论

匿名网友

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

确定