首页 > 解决方案 > 接口的同义结构字段和方法名称

问题描述

我正在构建一个类型结构,它代表我网络上的一些设备。这些设备有很多类型,例如:

type Foo struct  { ... }
type Bar struct  { ... }
type Spam struct { ... }

但它们都有一些共同的领域,其中之一是IP. 我想定义Device为一个接口,这样我就可以将它们逻辑地组合在一起

type Device interface {
    IP() string
    ...
}

type LogicalGrouping struct {
    Devices []Device
    ...
}

但我遇到了名称重叠的错误。

func (f *Foo) IP() string { return f.IP }  // same method name as field name

我可以重命名字段或方法或两者都重命名,但这肯定是一个常见的用例——按它们共有的字段对结构进行分组?这里有惯用的解决方案吗?

标签: gostructinterface

解决方案


一般的经验法则是接口定义行为,字段定义数据。

这里的问题是您正在使用接口来访问字段中的数据。就其本身而言,这不一定是一件坏事。但是您可能需要重新考虑如何构建代码,以免发生这种冲突。

我想的第一个问题是:

IP“如果struct定义了IP()可以访问它的方法,为什么需要导出该字段?”

您可以使 struct 字段未导出,即ipnot IP,然后在您使用的地方struct.IPstruct.IP()改为使用。

第二个问题是:

“如果您有 , 等结构,foo并且它们都共享公共字段,为什么不使用组合来删除这些共享字段的定义。”barspam

这可能只有在你真的只关注结构内的数据时才有效,我通常会提倡在所有情况下都使用接口。

如果您有以下结构:

type Foo struct {
    IP string
    A string 
    B string
}

type Bar struct {
    IP string
    A string 
    B string
}

type Spam struct {
    IP string
    A string 
    B string
}

您可以使用一个新结构来表示它们共有的字段,并在其中匿名组合:

type Inner struct {
    IP string
    A string 
    B string
}

type Foo struct {
    Inner
}

type Bar struct {
    Inner
}

type Spam struct {
    Inner
}

在您使用的函数调用中struct.IP(),接受一个Inner并使用struct.Inner. struct.IP即使IP在内部定义,您仍然可以访问Inner


推荐阅读