这是代码:
type field struct {
name string
}
func print(p *field) {
fmt.Println(p.name)
}
func fix1() {
data := []*field{{name: "one"}, {name: "two"}, {name: "three"}}
for _, v := range data {
go print(v)
}
time.Sleep(time.Millisecond * 200)
}
func wrong1() {
data := []*field{{name: "one"}, {name: "two"}, {name: "three"}}
for _, v := range data {
go func() {
print(v)
}()
}
time.Sleep(time.Millisecond * 200)
}
func main() {
wrong1()
}
Run Code Online (Sandbox Code Playgroud)
据我所知,函数中的所有goroutine wrong1共享相同的局部变量v.在执行goroutine时,值v可能等于任何值data …
据我所知,Golang中的类型slice和map方式在很多方面都很相似.它们都是reference(或container)类型.就抽象数据类型而言,它们分别表示数组和关联数组.
但是,他们的行为却截然不同.
var s []int
var m map[int]int
Run Code Online (Sandbox Code Playgroud)
虽然我们可以立即使用声明的切片(追加新项目或重新绑定它),但我们无法对新声明的地图执行任何操作.我们必须调用make函数并显式初始化一个映射.因此,如果某个struct包含一个map,我们必须为struct编写一个构造函数.
所以,问题是为什么在声明地图时不可能添加一些合成糖并分配和初始化内存.
我做了谷歌的问题,学会了一个新的词"avtovivification",但仍然没有看到原因.
补充:我不是在讨论struct literal.是的,您可以通过提供诸如的值来显式初始化地图m := map[int]int{1: 1}.但是,如果你有一些结构:
package main
import (
"fmt"
)
type SomeStruct struct {
someField map[int]int
someField2 []int
}
func main() {
s := SomeStruct{}
s.someField2 = append(s.someField2, -1) // OK
s.someField[0] = -1 // panic: assignment to entry in nil map
fmt.Println(s)
}
Run Code Online (Sandbox Code Playgroud)
不能立即使用结构(所有字段都使用默认值).必须创建一个构造函数SomeStruct,必须显式初始化一个映射.