Go 当T2的基础类型为T1时,从[]T1转换为[]T2
两个密切相关的问题: 如果Go 当T2的基础类型为T1时,从[]T1转换为[]T2,go,type-conversion,Go,Type Conversion,两个密切相关的问题: 如果T2的基础类型为T1,为什么不允许您将[]T1转换为[]T2 使用不安全的软件包进行转换的负面后果是什么 示例: 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
T2
的基础类型为T1
,为什么不允许您将[]T1
转换为[]T2
使用不安全的
软件包进行转换的负面后果是什么
示例:
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
}
操场:
用法示例:
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
}
如果T1实现了一个特定的接口,比如说json.Marshaler
,并且您希望以不同的方式对类型进行json编码,那么您可以使用自己的json.Marshaler
实现创建一个新的类型T2 T1
当封送单个值时,它可以正常工作,但是当您获得[]T1切片时,您必须将其复制到[]T2切片,或者使用自己的MarshalJSON()
方法创建一个新的type ST1[]T1
。最好做一个简单的转换,而不必转向safe
,因为这可能会导致运行时错误,而不是编译时错误
如果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}]
对不起,我不清楚。我更想知道为什么规格不允许。如果内存表示是相同的(显然它们具有相同的底层类型),为什么它们会决定阻止这种转换?我更新了我的问题。@Greg Go规范允许您从T1转换为T2,如果它们具有相同的基础类型。但不是从[]T1到[]T2;那么你将有一个编译器错误。@ANisus抓住你了,我误解了:)