英文:
Why are addresses of pointers to a WaitGroup different in this golang snippet?
问题
在playground上的代码片段中,我正在打印sync.WaitGroup
的指针地址,它们都是不同的。为什么会这样?
func Run() *sync.WaitGroup {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Printf("goroutine %p\n", &wg)
time.Sleep(5 * time.Second)
fmt.Println("wokeup")
}()
fmt.Printf("returning %p\n", &wg)
return &wg
}
func main() {
runtime.GOMAXPROCS(3)
wg := Run()
fmt.Printf(" main %p\n", &wg)
wg.Wait()
}
典型的输出显示,在函数Run
和main
内部的地址是不同的。我希望它们是相同的,难道不是吗?
returning 0xc0840045c0
main 0xc084000038
goroutine 0xc0840045c0
wokeup
英文:
Code snippet on playground
I am printing the pointer address for sync.WaitGroup
and they are all different. Why?
func Run() *sync.WaitGroup {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Printf("goroutine %p\n", &wg)
time.Sleep(5 * time.Second)
fmt.Println("wokeup")
}()
fmt.Printf("returning %p\n", &wg)
return &wg
}
func main() {
runtime.GOMAXPROCS(3)
wg := Run()
fmt.Printf(" main %p\n", &wg)
wg.Wait()
}
Typical output shows that the address is diff between that inside the function Run
and main
. I'd expect that to be the same, n'est-ce pas ?
returning 0xc0840045c0
main 0xc084000038
goroutine 0xc0840045c0
wokeup
答案1
得分: 1
好的,以下是翻译好的内容:
嗯,如果你注意到,"returning"的打印语句和"goroutine"的打印语句给出了相同的地址。你的"main"打印是有问题的。看看这一行代码:
fmt.Printf(" main %p\n", &wg)
你注意到了什么?你打印的是&wg
,也就是wg
被赋值的地址。
现在看看你的Run()
函数的返回值,你返回的是&wg
,也就是wg
作为变量的第一个声明的指针。
所以基本上你的"main"打印是打印了wg
指针地址的地址,而不是指针地址本身...希望这样说得清楚...
但是,是的,将"main"中的那一行代码改为
fmt.Printf(" main %p\n", wg)
应该可以解决问题。
英文:
Well, if you notice, the "returning" print statement and the "goroutine" print statement give the same address. Your "main" print is what is off. Look at the line:
fmt.Printf(" main %p\n", &wg)
What do you notice? You're printing &wg
, the address of whatever wg
is assigned to.
Now look at the return value of your Run()
function, you're returning &wg
. A pointer to your first declaration of wg
as a variable.
So basically your "main" print is printing the the address of the wg
pointer address rather than the pointer address itself... hope that makes sense...
But yeah, changing the line in "main" to
fmt.Printf(" main %p\n", wg)
should work.
答案2
得分: 1
例如,
package main
import "fmt"
import "sync"
import "time"
import "runtime"
func Run() *sync.WaitGroup {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Printf("goroutine %p\n", &wg)
fmt.Println("sleep for 5s")
time.Sleep(5 * time.Second)
fmt.Println("wokeup")
}()
fmt.Printf("returning %p\n", &wg)
return &wg
}
func main() {
runtime.GOMAXPROCS(3)
wg := Run()
fmt.Printf(" main %p\n", wg)
wg.Wait()
}
输出:
returning 0x1052e2c0
main 0x1052e2c0
goroutine 0x1052e2c0
sleep for 5s
将
fmt.Printf(" main %p\n", &wg)
改为
fmt.Printf(" main %p\n", wg)
在main
函数中,变量wg
包含了你想要的地址。你正在打印包含地址的变量的地址。
英文:
For example,
package main
import "fmt"
import "sync"
import "time"
import "runtime"
func Run() *sync.WaitGroup {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Printf("goroutine %p\n", &wg)
fmt.Println("sleep for 5s")
time.Sleep(5 * time.Second)
fmt.Println("wokeup")
}()
fmt.Printf("returning %p\n", &wg)
return &wg
}
func main() {
runtime.GOMAXPROCS(3)
wg := Run()
fmt.Printf(" main %p\n", wg)
wg.Wait()
}
Output:
returning 0x1052e2c0
main 0x1052e2c0
goroutine 0x1052e2c0
sleep for 5s
Change
fmt.Printf(" main %p\n", &wg)
to
fmt.Printf(" main %p\n", wg)
In main
, the variable wg
contains the address you want. You are printing the address of the variable that contains the address.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论