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

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

Declaring a pointer to a struct

问题

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

var b *Vertex
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.

var b *Vertex
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字段赋值有多种方法。例如,

package main

import "fmt"

type Vertex struct {
    X, Y float64
}

func main() {
    {
        var pv *Vertex
        pv = new(Vertex)
        pv.X = 4
        pv.Y = 2
        fmt.Println(pv)
    }

    {
        var pv = new(Vertex)
        pv.X = 4
        pv.Y = 2
        fmt.Println(pv)
    }

    {
        pv := new(Vertex)
        pv.X = 4
        pv.Y = 2
        fmt.Println(pv)
    }

    {
        var pv = &Vertex{4, 2}
        fmt.Println(pv)
    }

    {
        pv := &Vertex{4, 2}
        fmt.Println(pv)
    }
}

输出:

&{4 2}
&{4 2}
&{4 2}
&{4 2}
&{4 2}

参考资料:

Go编程语言规范

变量声明

短变量声明

取地址操作符

分配

复合字面量

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

package main

import "fmt"

type Vertex struct {
    X, Y float64
}

func NewVertex(x, y float64) *Vertex {
    return &Vertex{X: x, Y: y}
}

func (v *Vertex) Move(x, y float64) {
    v.X = x
    v.Y = y
}

func main() {
    v := NewVertex(4, 2)
    fmt.Println(v)
    v.Move(42, 24)
    fmt.Println(v)
}

输出:

&{4 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,

package main

import "fmt"

type Vertex struct {
	X, Y float64
}

func main() {
	{
		var pv *Vertex
		pv = new(Vertex)
		pv.X = 4
		pv.Y = 2
		fmt.Println(pv)
	}

	{
		var pv = new(Vertex)
		pv.X = 4
		pv.Y = 2
		fmt.Println(pv)
	}

	{
		pv := new(Vertex)
		pv.X = 4
		pv.Y = 2
		fmt.Println(pv)
	}

	{
		var pv = &Vertex{4, 2}
		fmt.Println(pv)
	}

	{
		pv := &Vertex{4, 2}
		fmt.Println(pv)
	}
}

Output:

&{4 2}
&{4 2}
&{4 2}
&{4 2}
&{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.

package main

import "fmt"

type Vertex struct {
	X, Y float64
}

func NewVertex(x, y float64) *Vertex {
	return &Vertex{X: x, Y: y}
}

func (v *Vertex) Move(x, y float64) {
	v.X = x
	v.Y = y
}

func main() {
	v := NewVertex(4, 2)
	fmt.Println(v)
	v.Move(42, 24)
	fmt.Println(v)
}

Output:

&{4 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 的指针,但没有对其进行任何初始化。你将得到一个空指针。

但是,类型是相同的。

你也可以这样做:

var d *Vertex
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:

var d *Vertex
d = &Vertex{3,3}

答案3

得分: 0

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

假设你有以下代码:

type Vertex struct {
} 

func (v *Vertex) Hello() {
   ... 做一些事情 ...
}

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

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

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

Let say you have this:

type Vertex struct {
} 

func (v *Vertex) Hello() {
   ... do something ...
}

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

d := &Vertex{}
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:

确定