Golang中,为什么指针使用星号操作符而不是&符号?

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

Golang, Go : why pointer use star operator instead of &

问题

这是你提供的代码:

type ByteSlice []byte

func (p *ByteSlice) Append(data []byte) {
  slice := *p
  slice = append(slice, data...)
  *p = slice
}

func main() {
  x := ByteSlice{1, 2, 3}
  y := []byte{4, 5}
  x.Append(y)
  fmt.Println(x)
}

我理解了指针的工作原理和用法,但我一直想知道为什么我们要使用*运算符来传递指针给函数。

  • *ptr用于解引用指针,并返回指针所指向的值。
  • &var返回变量var的地址。

为什么我们不使用&ByteSlice来传递指针给函数呢?

我感到困惑。难道这个函数不是传递指针吗?

根据Go语言规范(http://golang.org/ref/spec#Pointer_types)

> PointerType = "*" BaseType .
>
> BaseType = Type .

这也让我感到困惑。为什么我们在获取变量的指针和解引用指针时都使用星号(*)运算符?看起来在C和Go中,我们都不使用&来进行这种操作...

英文:

The code:

type ByteSlice []byte

func (p *ByteSlice) Append(data []byte) {
  slice := *p
  slice = append(slice, data...)
  *p = slice
}

func main() {
  x := ByteSlice{1, 2, 3}
  y := []byte{4, 5}
  x.Append(y)
  fmt.Println(x)
}

Ok, I understand why and how pointer works, but I've always wondered why we use * operator to pass pointer to function.

  • *ptr is to deference the ptr and return the value saved in the pointer ptr.
  • &var returns the address of the variable var.

Why we do not use &ByteSlice to pass pointer to function?

I am confused. Isn't this function passing pointer?

According to Go spec (http://golang.org/ref/spec#Pointer_types)

> PointerType = "*" BaseType .
>
> BaseType = Type .

This also confuses me. Why we use star(*) operator both to get the pointer of variable and dereference pointer? Looks like we don't use & for this case both in C and Go...

答案1

得分: 16

func (p *ByteSlice) Append(data []byte) { 中的 * 只是声明 p 是类型 *ByteSlice 的指针。

指针的传递发生在这里:

x.Append(y)

正如规范所说(我强调):

>如果方法集(类型的)x 包含 m 并且参数列表可以赋值给 m 的参数列表,则方法调用 x.m() 是有效的。如果 x 是可寻址的并且 &x 的方法集包含 m,则 x.m() 是 (&x).m() 的简写形式:

在你的情况下,x.Append(y)(&x).Append(y) 的简写形式。这就是你看到的 & 符号。

英文:

The * in func (p *ByteSlice) Append(data []byte) { is simply declaring that p is of type *ByteSlice.

The passing of a pointer takes place here:

x.Append(y)

As the Specification says (my emphasis):

>A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m():

In your case, x.Append(y) is a shorthand for (&x).Append(y). There you have your &-sign.

huangapple
  • 本文由 发表于 2014年1月30日 17:17:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/21452165.html
匿名

发表评论

匿名网友

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

确定