如何在单个函数中传递多类型数组

时间:2019-03-13 12:29:56

标签: go

我有多个结构

type Base struct {
    Id string
    Name string
    Code string
}
type Country struct {
    Base
    ...
}
type City struct {
    Base
    ...
}

我需要制作一个包含一个城市或国家/地区数组的函数。目前,每种类型的我都具有一个功能相同的功能,我想这并不是最好的/好方法!

谢谢

2 个答案:

答案 0 :(得分:3)

您似乎正在尝试在Go中重新创建类继承。 Go故意没有类继承。不要尝试重新创建它。我相信您正在考虑“国家是基地”。那是不对的。国家嵌入个基地。那不是同一回事。这对您如何命名事物很重要。在这种情况下,“基本”实际上就是“位置元数据”,因此我们将其称为。

type LocationMeta struct {
    id   string
    name string
    code string
}

并且您想要一个适用于各种位置的界面。

type Location interface {
    Id() string
    Name() string
    Code() string
}

我们可以使LocationMeta符合Location,尽管这可能有点奇怪(元数据真的是Location吗?)。但这有效。

func (b LocationMeta) Id() string {
    return b.id
}

func (b LocationMeta) Name() string {
    return b.name
}

func (b LocationMeta) Code() string {
    return b.code
}

我们可以在城市中嵌入LocationMeta:

type City struct {
    LocationMeta
}

免费,城市现在符合位置。

也就是说,通常情况下,您不必为这种很小的东西而没有这种逻辑的嵌入而烦恼。那真是太过分了;我只是在演示它,因为您似乎正在使用它。通常,您只需符合每种类型本身即可:

type Country struct {
    id   string
    name string
    code string
}

func (c Country) Id() string {
    return c.id
}

func (c Country) Name() string {
    return c.name
}

func (c Country) Code() string {
    return c.code
}

Go的优点在于,它并不关心您如何遵循界面。城市和国家/地区都以完全不同的方式符合位置,​​这完全可以。

因此您可以创建一个城市:

boston := City{LocationMeta{id: "bos", name: "Boston", code: "bos"}}

看看这有多奇怪?由于嵌入的对象,我们必须创建一个LocationMeta。有时候这是值得的(并且功能非常强大),但我可能会以“乡村”和“乡村”两种方式(没有LocationMeta)来完成:

us := Country{id: "us", name: "USA", code: "us"}

但是,它们都是位置,所以我们可以将它们切成薄片:

locations := []Location{boston, us}

并将它们传递给事物:

func printLocations(locations []Location) {
    fmt.Println(locations)
}

printLocations(locations)

Playground of this code

Playground using embedding for everything

Playground of more typical approach with just structs

答案 1 :(得分:1)

我已经在评论中发布了此内容,但是您可以这样做

func myfunc(in interface{}) {
    switch in.(type) {
    case []Country:
        // country logic here
    case []City:
        // city logic here
    }
}