【问题标题】:Why can't a struct be converted to an embedded type为什么不能将结构转换为嵌入式类型
【发布时间】:2018-02-15 09:15:12
【问题描述】:
package main

type Inner struct {
    x int
}

type Outer struct {
    Inner
}

func main() {
    x := Inner{1}
    y := (Outer)(x) // cannot convert x (type Inner) to type Outer
}

conversions 上的 go 规范部分声称

在以下任何一种情况下,非常量值 x 都可以转换为类型 T: ... 忽略结构标签(见下文),x 的类型和 T 具有相同的基础类型。 ...

type identity 上的部分说:

如果两个结构类型具有相同的字段序列,并且对应的字段具有相同的名称、相同的类型和相同的标签,则它们是相同的。

据我了解,InnerOuter 都有一个字段 x,即 int。那么为什么我不能将Outer 转换为Inner

我最终发现我可以使用x.Inner,但我花了一段时间,所以我很好奇为什么(在我看来)更明显的方法被禁止。

【问题讨论】:

  • 我明白了,谢谢。我想这就是答案,那么?
  • 有人愿意解释反对票吗?与规范相关的问题是否离题?还是我没有做足够的研究?我确实阅读了我认为是规范的相关部分,但错过了type identitySelectors 之间的联系。尽管如此,我还是学到了一些关于 Go 的知识,所以感谢您的回答。

标签: go type-conversion


【解决方案1】:

Outer 没有字段x。它有一个字段Inner,它有一个字段x。访问.x时,选择器(.)会自动从有x的最浅深度提升嵌入字段。

请参阅 Selectors 上的规范

【讨论】:

    【解决方案2】:

    以下代码 sn-p 用于支持 JimB 的回答 - InnerOuter 不共享相同的字段序列,因此不符合转换条件。

    它将帮助您从字面上了解InnerOuter 类型之间的区别:

    package main
    
    import "fmt"
    
    type inner struct {
        x int
    }
    
    type outer struct {
        inner
    }
    
    func main() {
        in := inner{x: 1}
        fmt.Printf("inner: %+v\n", in)
        fmt.Println()
        out := outer{in}
        fmt.Printf("outer: %+v\n", out)
    }
    
    
    

    【讨论】:

    • 编译inner需要Innerouter需要Outer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 2018-11-04
    相关资源
    最近更新 更多