如何在go中将切片转换为别名切片?

如何在go中将切片转换为别名切片?,go,type-conversion,slice,Go,Type Conversion,Slice,我把int化名为int 我想将Int片转换为Int片,但出现编译错误: 无法将c(类型[]Int)转换为类型[]Int如何解决此问题?多谢各位 package main import ( "fmt" ) type Int int func main() { var c = []Int{} var x = []int( c ) fmt.Println(len(x)) } 问题是您没有将Int创建为别名,而是 type Int 将创建Int作为无法与Int互

我把int化名为int

我想将Int片转换为Int片,但出现编译错误:

无法将c(类型[]Int)转换为类型[]Int
如何解决此问题?多谢各位

package main

import (
    "fmt"
)

type Int int

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

问题是您没有将
Int
创建为别名,而是

type Int

将创建
Int
作为无法与
Int
互操作的新类型

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

type Int=Int


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

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

var c = []Int{1, 2}

x := make([]int, len(c))
for i, v := range c {
    x[i] = int(v)
}
fmt.Println(x)
输出(在上尝试):

不安全的方式 还有一种“不安全”的方式:

输出是相同的。试一试这个

这里发生的事情是,将
c
(即
&c
)的地址转换为(所有指针都可以转换为该地址),然后将该地址转换为
*[]int
不安全。指针
可以转换为任何指针类型),然后取消引用该指针,从而给出类型为
[]int
的值。在这种情况下,它是安全的,因为
[]Int
[]Int
的内存布局是相同的(因为
Int
Int
作为其基础类型),但一般来说,应尽可能避免使用包

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

var c = []Int{1, 2}

var x []int = c
fmt.Println(x)
输出与上面相同(请在上尝试)。之所以这样做,是因为编写
[]Int
与编写
[]Int
是相同的类型,因此您甚至不需要在此处进行转换

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

type IntSlice = []int

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

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

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

从技术上讲,
类型Int
并没有定义一个,而是一个全新的类型。尽管
Int
Int
现在具有相同的属性,并且可以相互转换,但这不适用于切片。有关允许的转换的更多信息,请参见。

实际上,片a只是指向指定类型的底层数组(在本例中,类型不同,
Int
Int
)。因此,除非基础类型相同,否则转换将不起作用。不过,为了说明这一点,类似这样的方法是可行的:

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)
}
游乐场:


正如@icza指出的那样,有一种
不安全的
方法&当然,您可以始终在每个元素上执行转换循环,这可能会很昂贵。

您所做的不是别名。您不需要别名。忘了那个词吧。以围棋为例,它解释了如何转换具有相同底层类型的类型。是否需要评论?这个答案对我来说很好。是的,downvoter应该写下他的观点,我正在投票弥补:)p.s.:我注意到你后来在你的答案中添加了一部分,顺便说一句,我也举例说明了我不知道为什么downvote,@johlo的答案确实显示了如何在Go(Go 1.9及更高)中创建别名。没有人提到Go中真实别名的存在。请看这里:
type IntSlice = []int

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

    var x []int = []int(c)
    fmt.Println(x)
}
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)
}