【发布时间】:2021-07-18 11:05:42
【问题描述】:
我读到了article 并决定自己重复这种行为并进行实验:
package main
import (
"fmt"
"time"
)
type User struct {
i int
token string
}
func NewUser(i int, token string) User {
user := User{token: fmt.Sprint(i), i: i}
return user
}
func (u *User) PrintAddr() {
fmt.Printf("%d (PrintAddr): %p\n", u.i, u)
}
func main() {
users := make([]User, 4)
for i := 0; i < 4; i++ {
user := NewUser(i, "")
users[i] = user
}
for i, user := range users {
go user.PrintAddr()
go users[i].PrintAddr()
}
time.Sleep(time.Second)
}
这是代码输出:
1 (PrintAddr): 0xc000056198
2 (PrintAddr): 0xc0000561b0
0 (PrintAddr): 0xc000056180
3 (PrintAddr): 0xc00000c030
3 (PrintAddr): 0xc00000c030
3 (PrintAddr): 0xc00000c030
3 (PrintAddr): 0xc00000c030
3 (PrintAddr): 0xc0000561c8
我也不明白,为什么3 (PrintAddr)中有4个是0xc00000c030,而最后一个不一样?
但是,如果我使用 pointer 数组而不是 value 数组,像这样,
func NewUser(i int, token string) *User {
user := &User{token: fmt.Sprint(i), i: i}
return user
}
// -snip-
func main() {
users := make([]*User, 4)
// -snip-
那么这里一切都很好,每个条目都用相同的地址打印了 2 次:
1 (PrintAddr): 0xc0000ae030
3 (PrintAddr): 0xc0000ae060
2 (PrintAddr): 0xc0000ae048
2 (PrintAddr): 0xc0000ae048
3 (PrintAddr): 0xc0000ae060
1 (PrintAddr): 0xc0000ae030
0 (PrintAddr): 0xc0000ae018
0 (PrintAddr): 0xc0000ae018
但是为什么文章中的情况在这里不适用,反而我没有收到很多3 (PrintAddr)呢?
【问题讨论】:
-
"我也搞不懂,为什么
3 (PrintAddr)中有4个是0xc00000c030,而最后一个不一样?" -- 的4个实例3 (PrintAddr): 0xc00000c030是user.PrintAddr()的结果。3 (PrintAddr): 0xc0000561c8实例和1,2,0 (PrintAddr) 0x...实例是users[i].PrintAddr()的结果。
标签: loops go pointers goroutine data-race