我正在构建一个表示网络上某些设备的类型结构。这些设备的类型很多,例如:
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
我可以重命名字段或方法,或者两者都重命名,但是可以肯定,这一定是常见的用例-按结构的共同字段对结构进行分组?这里有惯用的解决方案吗?
答案 0 :(得分:2)
一般的经验法则是,接口定义行为,而字段定义数据。
这里的问题是您正在使用接口来访问字段中的数据。就其本身而言,不一定是一件坏事。但是您可能想重新考虑如何构造代码,以免发生冲突。
我要回答的第一个问题:
“如果IP
定义了可以访问该字段的struct
方法,为什么要导出字段IP()
?”
您可以将struct字段设为未导出,即ip
而不是IP
,然后在使用struct.IP
的位置使用struct.IP()
。
第二个问题是:
“如果您拥有foo
,bar
,spam
之类的结构,并且它们都共享公共字段,那么为什么不使用组合删除这些共享字段的定义。” >
这可能仅在您真正只在结构内部的数据之后才起作用,我通常会提倡在所有情况下都使用接口。
如果您具有以下结构:
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
字段和GetIP
和SetIP
方法(或与此doc相应的IP
和SetIP
方法)-清晰,简洁,简单。