重用相同方法的不同结构

下面是简化的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,"\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,"\t")
    return fmt.Sprintf("A:\n" + string(out))
}

type B struct {
    ID   int
    Logo   string
}
func (u B) String() string {
    out,"\t")
    return fmt.Sprintf("B:\n" + string(out))
}
iCMS 回答:重用相同方法的不同结构

有什么方法可以只写一次?

TL; DR 可能不是。

在您的确切示例中,有两种方法都可以使用,但是两种方法在实际代码中都不是很有用,我希望它们都不能满足您的实际需求。

  1. 最明显的是只有一个类型,因为它们还是一样的。或将您的第二种类型复制为第一种:

    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
    
  2. 您可以使用结构嵌入。之所以可行,是因为您的结构包含完全相同的字段,因此它们都可以嵌入一个公共结构:

    type common struct  {
        Name string
    }
    
    func (u common) String() string {
        out,"\t")
        return fmt.Sprintf("A:\n" + string(out))
    }
    
    type A struct {
        common
    }
    
    type B struct {
        common
    }
    

但是,我希望您的两个结构也包含更多不共享的字段。这意味着这两种方法都不起作用。如示例2所示,您可以 嵌入具有公共值的结构,但是您的String()方法将仅可访问公共字段。查看示例in the playground

一种可能适用于您的方法,但绝对不能在所有情况下都适用,最后一种方法是在每种外部类型上编写自定义String()方法,从而将其称为嵌入式{{1} }函数来计算公共部分。当然,是否适合您在很大程度上取决于您想要哪种格式。我将在on my blog中讨论使用嵌入式结构this SO answer进行JSON封送的类似方法。由于您的String()方法实际上是在生成JSON,因此它也可能适用于您。

它可能看起来像这样:

String()
,

是的,Go中有一种方法可以做到这一点。但是它可能会或可能不会起作用,具体取决于您的确切用例。您可以使用embedded struct

它看起来像这样:

Go Playground

type Stringer struct {
   Name string
}

func (u Stringer) String() string {
    out,"\t")

    return fmt.Sprintf(string(out))
}

type A struct {
   Stringer
}

type B struct {
   Stringer
}

请注意,AB中但不在Stringer中的任何字段都不会包含在String() string的结果中。因此,如果您需要任何此类字段,这可能不适用于您的情况。

,

您可以使用类似的嵌入式结构来实现String方法

package main

import (
    "encoding/json"
    "fmt"
)

type A struct {
    embd
}

type B struct {
    embd
}

type embd struct {
    Name string
    typ  string
}

func (e embd) String() string {
    out,err := json.MarshalIndent(e,"\t")
    if err != nil {
        panic(err)
    }

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

func main() {
    a := A{embd{"Foo","A"}}
    fmt.Println(a.String())

    b := B{embd{"Bar","B"}}
    fmt.Println(b.String())
}
本文链接:https://www.f2er.com/1978560.html

大家都在问