声明一个指向结构体的指针。

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

Declaring a pointer to a struct

问题

我很困惑,因为在Go语言中似乎有两种初始化指向结构体的指针的方式,而且它们在逻辑上似乎有些相反。

  1. var b *Vertex
  2. var c &Vertex{3, 3}

为什么一个使用 * 而另一个使用 &,如果 b 和 c 有相同的结果类型?对于这个主题已经发布的帖子,我没有充分理解,对此我表示歉意。

在这个上下文中,我还没有完全理解 "receivers" 的含义。我熟悉的术语是 "引用 (a) 的"、"指向 (a) 的指针"、"地址 (a) 的" 和 "解引用" 或 "地址上的值"。

提前感谢你的帮助。

英文:

I'm confused because there seem to be two ways to initialize a pointer to a struct in the go language and they appear to me to be somewhat opposite in logic.

  1. var b *Vertex
  2. var c &Vertex{3 3}

Why does one use a * and the other use a & if b and c have the same resulting type? My apologies for not adequately understanding the posts already up related to this topic.

I am also not yet straight on the implications of "receivers" in this context. The terminology I am familiar with is "reference to (a)" or "pointer to (a)" or "address of (a)" and "de-reference of" or "value at address".

Thanks in advance for your help.

答案1

得分: 2

声明指向struct的指针并为struct字段赋值有多种方法。例如,

  1. package main
  2. import "fmt"
  3. type Vertex struct {
  4. X, Y float64
  5. }
  6. func main() {
  7. {
  8. var pv *Vertex
  9. pv = new(Vertex)
  10. pv.X = 4
  11. pv.Y = 2
  12. fmt.Println(pv)
  13. }
  14. {
  15. var pv = new(Vertex)
  16. pv.X = 4
  17. pv.Y = 2
  18. fmt.Println(pv)
  19. }
  20. {
  21. pv := new(Vertex)
  22. pv.X = 4
  23. pv.Y = 2
  24. fmt.Println(pv)
  25. }
  26. {
  27. var pv = &Vertex{4, 2}
  28. fmt.Println(pv)
  29. }
  30. {
  31. pv := &Vertex{4, 2}
  32. fmt.Println(pv)
  33. }
  34. }

输出:

  1. &{4 2}
  2. &{4 2}
  3. &{4 2}
  4. &{4 2}
  5. &{4 2}

参考资料:

Go编程语言规范

变量声明

短变量声明

取地址操作符

分配

复合字面量

方法使用接收器。例如,v 是 Vertex Move 方法的接收器。

  1. package main
  2. import "fmt"
  3. type Vertex struct {
  4. X, Y float64
  5. }
  6. func NewVertex(x, y float64) *Vertex {
  7. return &Vertex{X: x, Y: y}
  8. }
  9. func (v *Vertex) Move(x, y float64) {
  10. v.X = x
  11. v.Y = y
  12. }
  13. func main() {
  14. v := NewVertex(4, 2)
  15. fmt.Println(v)
  16. v.Move(42, 24)
  17. fmt.Println(v)
  18. }

输出:

  1. &{4 2}
  2. &{42 24}

参考资料:

Go编程语言规范

方法集

方法声明

调用

方法表达式

方法值

英文:

There are a number of ways to declare a pointer to a struct and assign values to the struct fields. For example,

  1. package main
  2. import "fmt"
  3. type Vertex struct {
  4. X, Y float64
  5. }
  6. func main() {
  7. {
  8. var pv *Vertex
  9. pv = new(Vertex)
  10. pv.X = 4
  11. pv.Y = 2
  12. fmt.Println(pv)
  13. }
  14. {
  15. var pv = new(Vertex)
  16. pv.X = 4
  17. pv.Y = 2
  18. fmt.Println(pv)
  19. }
  20. {
  21. pv := new(Vertex)
  22. pv.X = 4
  23. pv.Y = 2
  24. fmt.Println(pv)
  25. }
  26. {
  27. var pv = &Vertex{4, 2}
  28. fmt.Println(pv)
  29. }
  30. {
  31. pv := &Vertex{4, 2}
  32. fmt.Println(pv)
  33. }
  34. }

Output:

  1. &{4 2}
  2. &{4 2}
  3. &{4 2}
  4. &{4 2}
  5. &{4 2}

References:

The Go Programming Language Specification

Variable declarations

Short variable declarations

Address operators

Allocation

Composite literals

Receivers are used for methods. For example, v is the receiver for the Vertex Move Method.

  1. package main
  2. import "fmt"
  3. type Vertex struct {
  4. X, Y float64
  5. }
  6. func NewVertex(x, y float64) *Vertex {
  7. return &Vertex{X: x, Y: y}
  8. }
  9. func (v *Vertex) Move(x, y float64) {
  10. v.X = x
  11. v.Y = y
  12. }
  13. func main() {
  14. v := NewVertex(4, 2)
  15. fmt.Println(v)
  16. v.Move(42, 24)
  17. fmt.Println(v)
  18. }

Output:

  1. &{4 2}
  2. &{42 24}

References:

The Go Programming Language Specification

Method sets

Method declarations

Calls

Method expressions

Method values

答案2

得分: 1

var c = &Vertex{3, 3}(你需要=)声明了一个结构体,并获取了对它的引用(实际上是分配了结构体的内存,然后获取了对该内存的引用(指针))。

var b *Vertex 声明了一个指向 Vertex 的指针,但没有对其进行任何初始化。你将得到一个空指针。

但是,类型是相同的。

你也可以这样做:

  1. var d *Vertex
  2. d = &Vertex{3,3}
英文:

var c = &Vertex{3, 3} (you do need the =) is declaring a struct and then getting the reference to it (it actually allocates the struct, then gets a reference (pointer) to that memory).

var b *Vertex is declaring b as a pointer to Vertex, but isn't initializing it at all. You'll have a nil pointer.

But yes, the types are the same.

You can also do:

  1. var d *Vertex
  2. d = &Vertex{3,3}

答案3

得分: 0

除了Wes Freeman提到的内容,你还问到了接收器。

假设你有以下代码:

  1. type Vertex struct {
  2. }
  3. func (v *Vertex) Hello() {
  4. ... 做一些事情 ...
  5. }

在这里,Vertex结构体是Hello()函数的接收器。因此,你可以这样做:

  1. d := &Vertex{}
  2. d.Hello()
英文:

In addition to what Wes Freeman mentioned, you also asked about receivers.

Let say you have this:

  1. type Vertex struct {
  2. }
  3. func (v *Vertex) Hello() {
  4. ... do something ...
  5. }

The Vertex struct is the receiver for the func Hello(). So you can then do:

  1. d := &Vertex{}
  2. d.Hello()

huangapple
  • 本文由 发表于 2013年12月29日 13:24:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/20822427.html
匿名

发表评论

匿名网友

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

确定