go - 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))
}
解决方案
您的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)
输出(在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
是相同的(因为Int
hasint
作为其底层类型),但通常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上试试这个。
推荐阅读
- sql-server - 使用 Azure VM Sql 服务器数据库作为 Azure Analysis Services 模型的源
- javascript - 如何防止进入未来日期角度4
- android - 用于绑定通用视图的 Android Kotling 扩展
- z3 - o.minimize() 没有给我最小的解决方案
- ms-access - DLookup 返回价格
- python - 如何从python脚本中查找我的计算机中某处是否存在目录(我不知道路径)
- java - artifactory-maven-plugin:如何在没有 settings.xml 的情况下解决私有 Artifactory 的依赖关系
- kubernetes - 注入 istio sidecar 时 pyspark 不起作用
- javascript - 如何让 javascript 在 Rspec Capybara 测试中运行
- r - 是否可以更改 fmsb 雷达图中标签的颜色?