接口的同义结构字段和方法名称

时间:2018-07-11 19:31:50

标签: go

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

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

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

2 个答案:

答案 0 :(得分:2)

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

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

我要回答的第一个问题:

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

您可以将struct字段设为未导出,即ip而不是IP,然后在使用struct.IP的位置使用struct.IP()

第二个问题是:

“如果您拥有foobarspam之类的结构,并且它们都共享公共字段,那么为什么不使用组合删除这些共享字段的定义。” >

这可能仅在您真正只在结构内部的数据之后才起作用,我通常会提倡在所有情况下都使用接口。

如果您具有以下结构:

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

答案 1 :(得分:1)

您也可以考虑选择具有ip字段和GetIPSetIP方法(或与此doc相应的IPSetIP方法)-清晰,简洁,简单。