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

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

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

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:

确定