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

标签 go type-conversion

两个密切相关的问题:

为什么不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

Conversions

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/

相关文章:

go - 为什么我的 “done” channel 随机关闭?

C++ 类型转换与隐式构造函数

java - 使用 .toArray 从 ArrayList[x]byte[] 转换为 byte[]?

go - 通过引用 fmt 传递参数

java - 错误: -Xdiag and String cannot be converted to int

MySQL 自动将字符串转换/转换为数字?

SQL 将 int 转换为 varchar

xml - 如何正确构建和嵌套结构以在 Go 中解码 SOAP 响应?

html - 如何在 Golang 中仅从 HTML 中提取文本?

multithreading - 如果一个 goroutine 已完成,控制 goroutine 关闭的规范方法是什么?