为什么这个golang片段中指向WaitGroup的指针地址不同?

时间:2014-04-08 05:52:07

标签: go

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()
}

典型输出显示函数Runmain内的地址差异很大。我希望这是相同的,不是最好的吗?

returning 0xc0840045c0
     main 0xc084000038
goroutine 0xc0840045c0
wokeup

2 个答案:

答案 0 :(得分:1)

好吧,如果你注意到,“返回”打印语句和“goroutine”打印语句给出相同的地址。你的“主要”印刷品是关闭的。看看这一行:

fmt.Printf("     main %p\n", &wg)

你注意到了什么?您正在打印&wg,即分配给wg的地址。

现在查看Run()函数的返回值,您将返回&wg。指向您的第一个wg声明为变量的指针。

所以基本上你的“主”打印是打印wg指针地址的地址而不是指针地址本身......希望这是有意义的......

但是,将“main”中的行更改为

fmt.Printf("     main %p\n", wg)

应该有用。

答案 1 :(得分:0)

例如,

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包含您想要的地址。您正在打印包含地址的变量的地址。