理解Go指针

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

Understanding Go Pointers

问题

我预期这段代码会生成4个地址,每个节点有2个地址,因此有2个相同的地址,然后另外一组2个相同的地址:

type node struct {
	identifier string
	parent     *node
	children   []*node
	root       int
}

func visitNodes(root *node) {	
	for i := 0; i < len(root.children); i++ {
		fmt.Printf("Visiting node %s\n", &root.children[i])
		printNodeAddress(root.children[i])
	}
}

func printNodeAddress(node *node) {
	fmt.Println(&node)
}


func main() {
	root := new(node)
	node1 := new(node)
	node2 := new(node)

	root.children = append(root.children, node1)
	root.children = append(root.children, node2)
	
	visitNodes(root)
}

产生的结果是:

Visiting node  %!s(**main.node=0x10500170)
0x10500180
Visiting node  %!s(**main.node=0x10500174)
0x10500190

而我期望它产生类似这样的结果:

Visiting node  %!s(**main.node=0x10500170)
0x10500170
Visiting node  %!s(**main.node=0x10500174)
0x10500174

我是否对Go指针的基本原理有误解,或者在处理切片时是否有所不同?

英文:

I expect this code to produce 4 addresses, 2 for each node, thus, having 2 identical addresses, and then another set of 2 identical addresses:

type node struct {
	identifier string
	parent     *node
	children   []*node
	root       int
}

func visitNodes(root *node) {	
	for i := 0; i &lt; len(root.children); i++ {
    	fmt.Printf(&quot;Visiting node %s\n&quot;, &amp;root.children[i])
    	printNodeAddress(root.children[i])
	}
}

func printNodeAddress(node *node) {
	fmt.Println(&amp;node)
}


func main() {
	root := new(node)
	node1 := new(node)
	node2 := new(node)

	root.children = append(root.children, node1)
	root.children = append(root.children, node2)
	
	visitNodes(root)
}

Produces:

Visiting node  %!s(**main.node=0x10500170)
0x10500180
Visiting node  %!s(**main.node=0x10500174)
0x10500190

While I expect it to produce something like this:

Visiting node  %!s(**main.node=0x10500170)
0x10500170
Visiting node  %!s(**main.node=0x10500174)
0x10500174

Am I misunderstanding the fundamentals of go pointers, or is different when dealing with slices?

答案1

得分: 5

问题在于你正在获取指针的地址:

func printNodeAddress(node *node) {
    fmt.Println(&node) // 这里有一个额外的间接层级,一个 **node
}

实际上,你想要看到的是指针的内存地址。你应该将你的 Printf 改为:

fmt.Printf("Visiting node %p\n", root.children[i])

并将你的 printNodeAddress 函数改为:

fmt.Printf("%p\n", node)

然后你会得到以下结果:

Visiting node 0x1052f2c0
0x1052f2c0
Visiting node 0x1052f2e0
0x1052f2e0
英文:

The issue is that you're taking the address of a pointer:

func printNodeAddress(node *node) {
    fmt.Println(&amp;node) // there&#39;s now a second layer of indirection in here. a **node
}

When really what you're trying to see is the pointer's memory address. You should change your Printf to this:

fmt.Printf(&quot;Visiting node %p\n&quot;, root.children[i])

And your printNodeAddress function to this:

fmt.Printf(&quot;%p\n&quot;, node)

Then you'll get this:

Visiting node 0x1052f2c0
0x1052f2c0
Visiting node 0x1052f2e0
0x1052f2e0

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

发表评论

匿名网友

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

确定