相关问题在这里https://stackoverflow.com/a/12965872/6421681。
在 go 中,您可以执行以下操作:
func numsInFactorial(n int) (nums []int) {
// `nums := make([]int)` is not needed
for i := 1; i <= n; i++ {
nums = append(nums, i)
}
return
}
但是,以下内容不起作用:
func mapWithOneKeyAndValue(k int, v int) (m map[int]int) {
m[k] = v
return
}
抛出一个错误:
panic: assignment to entry in nil map
相反,您必须:
func mapWithOneKeyAndValue(k int, v int) map[int]int {
m := make(map[int]int)
m[k] = v
return
}
我找不到此行为的文档。我已经通读了 effective go 的所有内容,那里也没有提到它。
我知道命名的返回值是定义的(即内存已分配;接近所做的new)但未初始化(因此make不会复制行为)。
经过一些实验,我相信这种行为可以简化为理解以下代码的行为:
func main() {
var s []int // len and cap are both 0
var m map[int]int
fmt.Println(s) // works... prints an empty slice
fmt.Println(m) // works... prints an empty map
s = append(s, 10) // returns a new slice, so underlying array gets allocated
fmt.Println(s) // works... prints [10]
m[10] = 10 // program crashes, with "assignment to entry in nil map"
fmt.Println(m)
}
这个问题似乎append很可能调用make并分配一个新的切片来检测容量s是0. 但是,map永远不会得到显式初始化。
这个 SO 问题的原因有两个。首先,我想记录下 SO 上的行为。slice其次,为什么该语言允许和的非初始化定义map?根据我到目前为止的经验,它似乎是一种实用的语言(即未使用的变量导致编译失败,gofmt 强制正确格式化),因此阻止代码编译是有意义的。
繁华开满天机
慕斯王
相关分类