如何将切片转换为别名切片?

时间:2018-05-17 08:00:53

标签: go

我将int别名为Int。

我想将一片Int转换为int片段,但是出现了编译错误:

cannot convert c (type []Int) to type []int我该如何解决这个问题?谢谢。

package main

import (
    "fmt"
)

type Int int

func main() {
    var c = []Int{}
    var x = []int( c )
    fmt.Println(len(x))
}

4 个答案:

答案 0 :(得分:5)

您的Int类型不是int的别名,它是int作为其基础类型的新类型。语言规范不支持/允许此类转换。更具体地说,不允许将切片类型转换为元素类型不同的另一种切片类型。

安全的方式

如果您只需要[]int"查看" []Int的安全方式转换"将创建[]Int切片的副本但类型为[]int,并使用for range循环并将每个元素从Int转换为int } type:

var c = []Int{1, 2}

x := make([]int, len(c))
for i, v := range c {
    x[i] = int(v)
}
fmt.Println(x)

输出(在Go Playground上尝试):

[1 2]

不安全的方式

还有一个"不安全的"方式:

var c = []Int{1, 2}

var x []int = *(*[]int)(unsafe.Pointer(&c))
fmt.Println(x)

输出是一样的。在Go Playground上试试这个。

这里发生的是c的地址(&c)被转换为unsafe.Pointer(所有指针都可以转换为此),然后转换为{{ 1}}(*[]int可以转换为任何指针类型),然后取消引用此指针,其值为unsafe.Pointer。在这种情况下,它是安全的,因为[]int[]Int的内存布局是相同的(因为[]int具有Int作为其基础类型),但一般来说,使用包应尽可能避免使用unsafe

如果int是" true"别名

请注意,如果Int为" true" Int的别名,甚至不需要转换:

int

输出与上述相同(在Go Playground上尝试)。这样做的原因是因为撰写var c = []Int{1, 2} var x []int = c fmt.Println(x) 与撰写[]Int相同,它们属于同一类型,因此您甚至不需要在此进行转换。

使用切片类型

另请注意,如果要创建一个以[]int作为基础类型的新类型,则可以使用类型转换:

[]int

输出再次相同。在Go Playground上试试这个。

答案 1 :(得分:0)

问题是您没有创建Int作为别名,正在执行

type Int int

Int创建为无法与int互操作的类型。

创建Int作为别名的正确方法是

type Int = int

通过此更改,您的程序就可以了。

答案 2 :(得分:0)

从技术上讲,type IntSlice = []int func main() { var c = IntSlice{1, 2} var x []int = []int(c) fmt.Println(x) } 并未定义alias,而是一种全新的类型。即使type Int intInt现在具有相同的underlying types并且可以相互转换,但这不适用于切片。有关允许转化的详情,请参见spec

答案 3 :(得分:0)

实际上,切片a只是指向指定类型的基础数组(在这种情况下,类型不同,intent.setType()Int)。因此,除非您的基础类型相同,否则转换将无效。只是为了说明这样的事情会起作用:

int

游乐场:https://play.golang.org/p/ROOX1XoXg1j

正如@icza所指出的那样package main import ( "fmt" ) type Int int type IntSl []int func main() { var c = IntSl{2, 3, 4} var x []int x = []int(c) var a Int var b int a = 1 b = int(a) fmt.Println(len(x), a, b, c) } 方式&当然,你总是可以对每个可能很昂贵的元素进行转换循环。