Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 当T2的基础类型为T1时,从[]T1转换为[]T2_Go_Type Conversion - Fatal编程技术网

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抓住你了,我误解了:)