英文:
first argument to append must be a slice; have untyped nil
问题
我是一个新手Go程序员,对下面的行为感到困惑。我预期程序在t2处会失败,并显示错误信息:
append的第一个参数必须是一个切片;而此处是无类型的nil
但是,当将nil作为第一个参数传递给一个方法时,Go却能够正常工作。这是一种方便的特性,还是我对此有误解?
package main
import "fmt"
type Thing struct {
data []string
}
func NewThing(extra []string) Thing {
return Thing{
data: append(extra, "b"),
}
}
func main() {
t := NewThing([]string{"a"})
fmt.Println(t.data) // [a b]
t2 := NewThing(nil)
fmt.Println(t2.data) // [b]
//_ = Thing{ // build failed: first argument to append must be a slice; have untyped nil
// data: append(nil, "b"),
//}
}
Playground: https://go.dev/play/p/Cxi7fRHu3Wi
这只是一种方便的特性,还是我对此有误解?
英文:
I'm a newbie Go programmer confused by the below behaviour. I expected the program to fail at t2 with error
> first argument to append must be a slice; have untyped nil
but Go is happy when passing in nil as first parameter to append when it's a parameter to a method?
package main
import "fmt"
type Thing struct {
data []string
}
func NewThing(extra []string) Thing {
return Thing{
data: append(extra, "b"),
}
}
func main() {
t := NewThing([]string{"a"})
fmt.Println(t.data) // [a b]
t2 := NewThing(nil)
fmt.Println(t2.data) // [b]
//_ = Thing{ // build failed: first argument to append must be a slice; have untyped nil
// data: append(nil, "b"),
//}
}
Playground: https://go.dev/play/p/Cxi7fRHu3Wi
Is this just a convenience feature or am I understanding this wrong?
答案1
得分: 2
这是一个方便的特性,nil切片的容量和长度都为零。因此,当传递一个nil切片时,append函数会正常工作。
调用append(nil, "b")无法编译通过,因为nil没有类型。编译器无法确定结果的类型,因为切片参数没有类型。
当extra为nil时,调用append(extra, "b")可以正常工作,因为extra是一个有类型的值([]string类型)。根据切片的类型,编译器知道结果是[]string类型,并且追加的元素必须可以赋值给string类型。
调用append([]string(nil), "b")也可以正常工作,因为表达式[]string(nil)是一个有类型的值。
英文:
It is a convenience that the capacity and length of a nil slice is zero. From there, append works as normal when passed a nil slice.
The call append(nil, "b") does not compile because nil has no type. The compiler cannot determine the type of the result because the slice argument does not have a type.
The call append(extra, "b") works when extra is nil because extra is a typed value (a []string). Given the slice type, the compiler knows that the result is []string and that the appended elements must be assignable to string.
The call append([]string(nil), "b") also works because the expression []string(nil) is a typed value.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论