两个密切相关的问题:
如果[]T1
的基础类型为[]T2
,为什么Go Specification不允许您将T2
转换为T1
?
使用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
}
游乐场: http://play.golang.org/p/x2tBRKuRF1
使用示例:
如果T1实现某个接口,比如说json.Marshaler
,并且您希望以不同的方式对该类型进行JSON编码,则可以使用自己的type T2 T1
实现创建一个新的json.Marshaler
。
在编组单个值时它可以正常工作,但是当你得到一个[] T1切片时,你必须将它复制到[] T2切片或者用自己的type ST1 []T1
创建一个新的MarshalJSON()
。方法。做一个简单的转换而不是转向unsafe
会很好,因为它可能会导致运行时错误而不是编译时间。
答案 0 :(得分:1)
The Go Programming Language Specification
如果x的类型和T,则非常数值x可以转换为类型T. 具有相同的基础类型。
例如,
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}]