首页 > 解决方案 > 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))
}

标签: gotype-conversionslice

解决方案


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

安全的方式

如果您只需要 的[]int“视图”,[]Int“转换”的安全方法是创建[]Int切片的副本但类型为[]int,并使用for range循环并将每个单独的元素从转换Intint类型:

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(which is &c) 的地址转换为unsafe.Pointer(所有指针都可以转换为 this), 然后转换为*[]int(unsafe.Pointer可以转换为任何指针类型), 然后 this 指针被取消引用, 给出一个值的类型[]int[]Int在这种情况下,它是安全的,因为and的内存布局[]int是相同的(因为Inthasint作为其底层类型),但通常unsafe应尽可能避免使用包。

如果Int将是“真实”别名

请注意,如果Int将是 的“真正”别名int,则甚至不需要转换:

var c = []Int{1, 2}

var x []int = c
fmt.Println(x)

输出与上面相同(在Go Playground上尝试)。之所以可行,是因为 writing与 writing[]Int是相同的[]int,它们是相同的类型,所以你甚至不需要在这里进行转换。

通过使用切片类型

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

type IntSlice = []int

func main() {
    var c = IntSlice{1, 2}

    var x []int = []int(c)
    fmt.Println(x)
}

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


推荐阅读