go - 不同的结构重用相同的方法

标签 go inheritance struct embedding

下面是简化的 Go 代码。
如您所见,它写了两次String() ,有没有办法只写一次?

type A struct {
    Name   string
}
func (u A) String() string {
    out, err := json.MarshalIndent(u, "", "\t")

    return fmt.Sprintf("A:\n" + string(out))
}

type B struct {
    Name   string
}
func (u B) String() string {
    out, err := json.MarshalIndent(u, "", "\t")

    return fmt.Sprintf("B:\n" + string(out))
}
类似于实现 struct Base , 它有一个方法 did() ,
然后 struct Astruct B实现struct Base ,所以他们可以调用did()无需执行did()又是自己。
===============
编辑:
之前的示例代码不是很清楚,现在改了。struct Astruct B有不同的字段,怎么写String()一次,然后应用于两个结构?
type A struct {
    Name     string
    Status   string
}
func (u A) String() string {
    out, err := json.MarshalIndent(u, "", "\t")
    return fmt.Sprintf("A:\n" + string(out))
}

type B struct {
    ID   int
    Logo   string
}
func (u B) String() string {
    out, err := json.MarshalIndent(u, "", "\t")
    return fmt.Sprintf("B:\n" + string(out))
}

最佳答案

Is there any way to write just once?


TL;DR 可能不是。
在您的确切示例中,有两种方法可以使用,但在实际代码中都不是很有用,我希望这两种方法都不能满足您的实际需求。
  • 最明显的是只有一种类型,因为无论如何它们都是相同的。或者使您的第二种类型成为第一种类型的副本:
    type A struct {
        Name   string
    }
    func (u A) String() string {
        out, err := json.MarshalIndent(u, "", "\t")
    
        return fmt.Sprintf("A:\n" + string(out))
    }
    
    type B A
    
  • 您可以使用结构嵌入。这是有效的,因为您的结构包含完全相同的字段,因此它们都可以嵌入一个公共(public)结构:
    type common struct  {
        Name string
    }
    
    func (u common) String() string {
        out, err := json.MarshalIndent(u, "", "\t")
        return fmt.Sprintf("A:\n" + string(out))
    }
    
    type A struct {
        common
    }
    
    type B struct {
        common
    }
    

  • 但是,我希望您的两个结构也包含更多未共享的字段。这意味着这两种方法都行不通。与示例 2 一样,您可以嵌入一个具有公共(public)值的结构,但随后您的 String()方法只能访问公共(public)字段。查看示例 in the playground
    最后一种方法,可能适用于您,但绝对不会适用于所有情况,是编写自定义 String()每个外部类型的方法,依次调用嵌入的 String()计算公共(public)部分的函数。当然,这是否适合您,很大程度上取决于您想要什么格式。我讨论了一种类似的 JSON 编码与嵌入式结构 on my blog 的方法。 ,并在 this SO answer .由于您的String()方法实际上是生成 JSON,它也可能适用于您。
    它可能看起来像这样:
    type common struct  {
        Name string
    }
    
    func (u common) String() string {
        out, err := json.MarshalIndent(u, "", "\t")
        return fmt.Sprintf("A:\n" + string(out))
    }
    
    type A struct {
        common
        Age int
    }
    
    func (u A) String() string {
        return fmt.Sprintf("%s Age: %d", u.common.String(), u.Age)
    }
    

    关于go - 不同的结构重用相同的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62789515/

    相关文章:

    struct - 从结构映射调用结构

    具有灵活数组成员的常量结构

    java - 如何在 Java 的实现类中的抽象类中实现抽象类?

    Java/泛型 : Return a list of extending a type?

    qt - 在 QDockWidget 中停靠的小部件顶部绘画/绘图

    c++ - 如何声明一个 std::array of structs initialized inline with different values

    c - 在结构数组上重新分配,索引时地址边界错误

    go - 如何在 Go 中解析包含各种元素的巨大 XML 文件?

    jquery - 戈朗 : Nested XML to JSON

    go - 第三方库(闭源)