第一个参数必须是一个切片;而你传递的是未定义类型的空值。

huangapple go评论122阅读模式
英文:

first argument to append must be a slice; have untyped nil

问题

我是一个新手Go程序员,对下面的行为感到困惑。我预期程序在t2处会失败,并显示错误信息:

append的第一个参数必须是一个切片;而此处是无类型的nil

但是,当将nil作为第一个参数传递给一个方法时,Go却能够正常工作。这是一种方便的特性,还是我对此有误解?

  1. package main
  2. import "fmt"
  3. type Thing struct {
  4. data []string
  5. }
  6. func NewThing(extra []string) Thing {
  7. return Thing{
  8. data: append(extra, "b"),
  9. }
  10. }
  11. func main() {
  12. t := NewThing([]string{"a"})
  13. fmt.Println(t.data) // [a b]
  14. t2 := NewThing(nil)
  15. fmt.Println(t2.data) // [b]
  16. //_ = Thing{ // build failed: first argument to append must be a slice; have untyped nil
  17. // data: append(nil, "b"),
  18. //}
  19. }

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?

  1. package main
  2. import "fmt"
  3. type Thing struct {
  4. data []string
  5. }
  6. func NewThing(extra []string) Thing {
  7. return Thing{
  8. data: append(extra, "b"),
  9. }
  10. }
  11. func main() {
  12. t := NewThing([]string{"a"})
  13. fmt.Println(t.data) // [a b]
  14. t2 := NewThing(nil)
  15. fmt.Println(t2.data) // [b]
  16. //_ = Thing{ // build failed: first argument to append must be a slice; have untyped nil
  17. // data: append(nil, "b"),
  18. //}
  19. }

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没有类型。编译器无法确定结果的类型,因为切片参数没有类型。

extranil时,调用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.

huangapple
  • 本文由 发表于 2022年6月18日 09:17:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/72666028.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定