两个密切相关的问题:
为什么不Go Specification如果 T2
的基础类型为 T1
,是否允许您将 []T1
转换为 []T2
?
使用 unsafe
包进行转换的负面后果是什么?
示例:
package main
import (
"fmt"
"unsafe"
)
type T1 struct {
Val int
}
// T2 has the underlying type of T1
type T2 T1
func main() {
a := []T1{T1{12}}
// cannot convert a (type []T1) to type []T2
//b := ([]T2)(a)
// But with some unsafe we can do it.
// So, why doesn't Go allow it? And what unforeseen consequence might it have?
b := *(*[]T2)(unsafe.Pointer(&a))
b[0].Val = 42
fmt.Println(a[0].Val) // 42
}
Playground : http://play.golang.org/p/x2tBRKuRF1
使用示例:
如果 T1 实现了某个接口(interface),例如 json.Marshaler
,并且您希望以不同的方式对类型进行 JSON 编码,您可以创建一个新的 type T2 T1
它自己的 json.Marshaler
实现。
它在编码单个值时工作正常,但是当您获得 []T1 slice 时,您必须将其复制到 []T2 slice 或创建一个新的 type ST1 []T1
它自己的 MarshalJSON()
方法。做一个简单的转换而不是必须转向 unsafe
会很好,因为它可能会导致运行时错误而不是编译时错误。
最佳答案
The Go Programming Language Specification
A non-constant value x can be converted to type T if x's type and T have identical underlying types.
例如,
package main
import (
"fmt"
)
type T1 struct {
Val int
}
type T2 T1
type ST1 []T1
type ST2 ST1
func main() {
a := ST1{T1{42}}
fmt.Println(a) // 42
// convert a (type ST1) to type []ST2
b := ST2(a)
fmt.Println(b) // 42
}
输出:
[{42}]
[{42}]
关于go - 当 T2 具有 T1 的基础类型时,从 []T1 转换为 []T2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23353757/