将一段字符串转换为一段自定义类型 [英] Conversion of a slice of string into a slice of custom type

查看:124
本文介绍了将一段字符串转换为一段自定义类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Go很新,所以这可能很明显。编译器不允许使用以下代码:
http://play.golang.org/p / 3sTLguUG3l

 软件包主

导入fmt

类型卡串
类型手[]卡

func NewHand(卡[]卡)手{
hand:=手(卡)
返回手


func main(){
value:= [] string {a,b,c}
firstHand:= NewHand值)
fmt.Println(firstHand)
}

错误是:
/tmp/sandbox089372356/main.go:15:不能使用value(type [] string)作为类型[] Card中的参数给NewHand



从规格看,[]字符串与[] Card不同,因此不能进行类型转换。



事实确实如此,或者我错过了什么?

如果是这样,为什么这样?假设在一个非宠物示例程序中,我输入了一个字符串片段,是否有任何方法将它投射到一张卡片中,还是必须创建一个新结构并将数据复制到它中? (这是我想避免的,因为我需要调用的函数将修改切片内容)。

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



您无法转换切片 T1 T2 的片段,这不是他们拥有的底层类型的问题,如果 T1 T2 不完全相同,你不能。为什么?由于不同元素类型的切片可能具有不同的内存布局(内存中的大小不同)。例如,类型为 [] byte 的元素每个占用1个字节。 [] int32 的元素每个占用4个字节。显然,即使所有值都在 0..255 范围内,您也不能将其转换为另一个。



<但回到根源:如果你需要一块 Card s,为什么要创建一个字符串首先?您创建了类型 卡片,因为它不是 a 字符串(或者至少不只是一个字符串)。如果是这样,你需要 [] Card ,那么首先创建 [] Card ,所有问题都会消失:

  value:= [] Card {a,b,c} 
firstHand: = NewHand(value)
fmt.Println(firstHand)

请注意,您仍然可以用 untyped 常量字符串 文字初始化 Card片段 >因为它可以用来初始化其基础类型为 string 的任何类型。如果你想要涉及类型 string 常量或类型为 string 的非常量表达式,则需要显式转换,如in下面的例子:

  s:=ddd
value:= [] Card {a,如果你有一个





$ b $ > [] string
,你需要手动建立一个 [] Card 。没有更容易的方式。您可以创建一个助手 toCards()函数,以便您可以在任何需要的地方使用它。

  func toCards(s [] string)[]卡{
c:= make([] Card,len(s))
for i,v:= range s {
c [i] = Card(v)
}
返回c
}

一些用于背景和推理的链接:

Go Language Specification:Conversions



为什么[]字符串无法在golang中转换为[] interface {}



无法将[]字符串转换为[]界面{}



什t关于内存布局意味着[] T无法在Go中转换为[]接口?


I'm quite new to Go, so this might be obvious. The compiler does not allow the following code: (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)
}

The error is: /tmp/sandbox089372356/main.go:15: cannot use value (type []string) as type []Card in argument to NewHand

From the specs, it looks like []string is not the same underlying type as []Card, so the type conversion cannot occur.

Is it, indeed, the case, or did I miss something?

If it is the case, why is it so? Assuming, in a non-pet-example program, I have as input a slice of string, is there any way to "cast" it into a slice of Card, or do I have to create a new structure and copy the data into it? (Which I'd like to avoid since the functions I'll need to call will modify the slice content).

解决方案

The underlying type of Card might be the same as the underlying type of string (which is itself: string), but the underlying type of []Card is not the same as the underlying type of []string (and therefore the same applies to Hand).

You cannot convert a slice of T1 to a slice of T2, it's not a matter of what underlying types they have, if T1 is not identical to T2, you just can't. Why? Because slices of different element types may have different memory layout (different size in memory). For example the elements of type []byte occupy 1 byte each. The elements of []int32 occupy 4 bytes each. Obviously you can't just convert one to the other even if all values are in the range 0..255.

But back to the roots: if you need a slice of Cards, why do you create a slice of strings in the first place? You created the type Card because it is not a string (or at least not just a string). If so and you require []Card, then create []Card in the first place and all your problems go away:

value := []Card{"a", "b", "c"}
firstHand := NewHand(value)
fmt.Println(firstHand)

Note that you are still able to initialize the slice of Card with untyped constant string literals because it can be used to initialize any type whose underlying type is string. If you want to involve typed string constants or non-constant expressions of type string, you need explicit conversion, like in the example below:

s := "ddd"
value := []Card{"a", "b", "c", Card(s)}

If you have a []string, you need to manually build a []Card from it. There is no "easier" way. You can create a helper toCards() function so you can use it everywhere you need it.

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

Some links for background and reasoning:

Go Language Specification: Conversions

why []string can not be converted to []interface{} in golang

Cannot convert []string to []interface {}

What about memory layout means that []T cannot be converted to []interface in Go?

这篇关于将一段字符串转换为一段自定义类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆