一尘不染

将字符串切片转换为自定义类型的切片

go

我刚开始使用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

从规格上看,[] string看起来与[] Card不是相同的基础类型,因此无法进行类型转换。

确实是这样,还是我错过了什么?

如果是这样,为什么会这样呢?假设在一个非宠物示例程序中,我输入了一个字符串切片,是否可以将其“投射”到Card切片中,或者是否必须创建一个新结构并将数据复制到其中?(我想避免这种情况,因为我需要调用的函数会修改切片内容)。


阅读 249

收藏
2020-07-02

共1个答案

一尘不染

的基础类型Card可能与的基础类型string(本身是string)相同,但是的基础类型[]Card与的基础类型不同[]string(因此适用于Hand)。

您不能将的片转换T1为的片T2,这与它们具有什么基础类型T1无关,如果不相同T2,就不能。为什么?因为不同元素类型的切片可能具有不同的内存布局(内存大小不同)。例如,类型的元素[]byte每个占用1个字节。每个元素[]int32占用4个字节。显然,即使所有值都在范围内,也不能将一个转换为另一个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()函数,以便可以在需要的任何地方使用它。

func toCards(s []string) []Card {
    c := make([]Card, len(s))
    for i, v := range s {
        c[i] = Card(v)
    }
    return c
}
2020-07-02