我刚开始使用Go,所以这很明显。编译器不允许以下代码:(http://play.golang.org/p/3sTLguUG3l)
package main import "fmt" type Card string type Hand []Card func NewHand(cards []Card) Hand { hand := Hand(cards) return hand } func main() { value := []string{"a", "b", "c"} firstHand := NewHand(value) fmt.Println(firstHand) }
错误是: /tmp/sandbox089372356/main.go:15: cannot use value (type []string) as type []Card in argument to NewHand
/tmp/sandbox089372356/main.go:15: cannot use value (type []string) as type []Card in argument to NewHand
从规格上看,[] string看起来与[] Card不是相同的基础类型,因此无法进行类型转换。
确实是这样,还是我错过了什么?
如果是这样,为什么会这样呢?假设在一个非宠物示例程序中,我输入了一个字符串切片,是否可以将其“投射”到Card切片中,或者是否必须创建一个新结构并将数据复制到其中?(我想避免这种情况,因为我需要调用的函数会修改切片内容)。
的基础类型Card可能与的基础类型string(本身是string)相同,但是的基础类型[]Card与的基础类型不同[]string(因此适用于Hand)。
Card
string
[]Card
[]string
Hand
您不能将的片转换T1为的片T2,这与它们具有什么基础类型T1无关,如果不相同T2,就不能。为什么?因为不同元素类型的切片可能具有不同的内存布局(内存大小不同)。例如,类型的元素[]byte每个占用1个字节。每个元素[]int32占用4个字节。显然,即使所有值都在范围内,也不能将一个转换为另一个0..255。
T1
T2
[]byte
[]int32
0..255
但是要追溯到根本:如果需要切片Cards,为什么首先要创建切片strings?您所创建的 类型 Card,因为它 不是 一个string(或至少不只是一个string)。如果是这样,而您需要[]Card,那么[]Card首先创建,所有问题都将消失:
value := []Card{"a", "b", "c"} firstHand := NewHand(value) fmt.Println(firstHand)
请注意,您仍然可以Card使用未 类型化的 常量string 文字 来初始化的切片,因为它可用于初始化其基础类型为的任何类型string。如果要涉及类型化的类型string常量或非常量表达式string,则需要进行显式转换,例如下面的示例:
s := "ddd" value := []Card{"a", "b", "c", Card(s)}
如果您有一个[]string,则需要从中手动构建一个[]Card。没有“更轻松”的方式。您可以创建一个辅助toCards()函数,以便可以在需要的任何地方使用它。
toCards()
func toCards(s []string) []Card { c := make([]Card, len(s)) for i, v := range s { c[i] = Card(v) } return c }