当T2具有基础类型T1时,从[] T1转换为[] T2

时间:2014-04-29 01:01:34

标签: go type-conversion

两个密切相关的问题:

如果[]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会很好,因为它可能会导致运行时错误而不是编译时间。

1 个答案:

答案 0 :(得分:1)

  

The Go Programming Language Specification

     

Conversions

     

如果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}]