英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论