Go语言 具有相同基础类型的类型转换结构

dauxcl2d  于 2023-09-28  发布在  Go
关注(0)|答案(2)|浏览(112)

对于基本类型,如果它们的底层类型相同,我们可以很容易地转换类型。但是具有相同内存布局的结构体中的字段不能很容易地从一种类型转换为另一种类型。这个问题有一个proposal,不幸的是,它被拒绝了。经过一个小时的谷歌搜索没有运气,我来到这里寻求Maven的帮助。
看看下面的例子:

package main

import (
    "fmt"
)

type Int int

type A struct {
    name string
    age  Int
}
type B struct {
    name string
    age  int
}

func main() {
    var a A= A{"Foo",21}
    var b B= B{"Bar", 21}
    fmt.Println(a,b,(A)(b))  //Error here as expected
}

即使结构A和B具有相同的基础类型struct { string,int},为什么我不能转换为彼此,因为Int的基础类型是int。是否可以递归地强制转换,除非基础类型不同?

lmvvr0a8

lmvvr0a81#

你不能这么做,因为语言规范不允许这么做。对于结构,只有在以下情况下才能从一种类型转换为另一种类型:转换:
在以下任何情况下,非常量值x都可以转换为T类型:

  • ...
  • 忽略struct标记(见下文),x的类型和T具有相同的底层类型。

如果你完全确定结构体的内存布局是相同的,你可以使用一个不安全的转换(使用包unsafe),如下所示:

var a A = A{"Foo", 21}
var b B

b = *(*B)(unsafe.Pointer(&a))
fmt.Println(a, b)

这将输出(在Go Playground上尝试):

{Foo 21} {Foo 21}

**但请将此作为最后的手段。**使用unsafe将失去编译时类型安全性和可移植性保证。例如,如果稍后您只修改了其中一个结构体,则上述代码将继续编译,即使它可能不再正确,编译器也无法通知您。

5vf7fwbs

5vf7fwbs2#

在您的程序中不允许此转换的原因:

type A B   // this isn't a type alias

在本例中,A具有与B相同的二进制结构。然而,A根本没有继承任何与B关联的方法!
让我们假设这段代码:

func (b B) method()

以下是有效的

var b B
b.method()

这是无效的

var a A
a.method() // for type A no method of name 'method' exists

Spec假设A和B确实可能非常不同。所以不允许类型转换。
你可以使用这样的类型别名:

type Int = int

这是一个Playground链接。

相关问题