我将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))
}
答案 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 int
和Int
现在具有相同的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)
}
方式&当然,你总是可以对每个可能很昂贵的元素进行转换循环。