【问题标题】:Using a struct member as a member in another struct将结构成员用作另一个结构中的成员
【发布时间】:2015-04-13 05:00:32
【问题描述】:
type (
    A struct {
        a string
    }

    B struct {
        b *A.a
    }
)

我收到此错误:

A.a undefined (type A has no method a)

我在这里遗漏了什么吗?还是 Go 中不允许?

【问题讨论】:

    标签: go struct embedding


    【解决方案1】:

    定义结构字段时,必须指定its name and its type,就像使用结构A.a 一样。但是在结构B:

    b *A.a
    

    *A.a 不是类型。

    您不能将struct 的字段嵌入到另一个结构中。请注意,您可以通过省略 name 部分将 complete 结构嵌入到另一个结构中,如下所示:

    type (
        A struct {
            a string
        }
    
        B struct {
            A
        }
    )
    

    结果是A 类型的所有字段和方法也将成为结构B 的成员。如果需要B的内嵌结构体A,可以通过引用类型名来访问:

    var b B
    fmt.Println(b.A)
    

    您可以做的另一件事是在B 中有一个字段,它是一个指针,它指向A 类型的现有值 的字段:

    B struct {
        ap *string
    }
    
    a := A{a:"test"}
    b := B{ap:&a.a} // B.ap will point to a.a
    
    fmt.Println(*b.ap) // Prints "test"
    

    【讨论】:

      【解决方案2】:

      问题是您使用*A.a 作为字段b 的类型说明符。您唯一缺少的是您应该在那里拥有b stringb *string(如果您至少想要结构B 中的字符串字段)。

      现在,如果您的目标是更类似于“继承”该字段,那么您应该嵌入AB 中,这将为B 提供一个名为a 的属性。看起来像这样;

      type B struct {
            A
      }
      

      这是与 Go 提供的继承最相似的构造。如果您要嵌入此处,则可以执行以下操作;

      var instanceOfB = &B{}
      fmt.Println(instanceOfB.a)
      

      这在功能上等同于让 B 从 A 继承(在这种情况下,尽管两者并不相同,而且许多行为也不同。我只是认为比较/对比继承很有帮助)。此时,您可以直接从B 的实例访问A 上的属性或方法。最好避免名称冲突,尽管它们不会导致编译器错误。如果您确实在嵌入式类型或嵌入器和嵌入式类型之间存在命名冲突,则在运行时决定使用哪个方法/属性,我不确定解析规则是什么,但我认为您可以在语言中找到它们规格。

      现在我的最后一个想法...如果您的目标是从B 的某个实例中引用A 实例中的a 属性,您只需在B 中包含一个刺指针并设置当您实例化B 时,它在构造函数中的&A.a 是一个静态初始化器。然而,这可能是一种不好的做法,因为它违反了封装的概念,而且很明显容易出错。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-28
        • 1970-01-01
        • 1970-01-01
        • 2013-04-19
        • 2020-11-25
        • 1970-01-01
        • 2017-06-11
        相关资源
        最近更新 更多