dongzai2952 2018-07-11 19:31
浏览 44
已采纳

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

I'm building a type structure that represents some devices on my network. There are lots of types of these devices, such as:

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

but they all share a few common fields, one of which is IP. I'd like to define Device as an interface so I can group these together logically

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

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

but I'm running into an error with overlapping names.

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

I can rename either the field or the method or both, but surely this must be a common use case -- grouping structs by the fields they have in common? Is there an idiomatic solution here?

  • 写回答

2条回答 默认 最新

  • doudu5029 2018-07-12 08:31
    关注

    The general rule of thumb is that interfaces define behaviours and fields define data.

    The problem here is that you are using an interface to access data in fields. On it's own that's not necessarily a bad thing. But you might want to reconsider how to structure your code so that you don't get this collision.

    The first question I would as is:

    "Why do you need to export the field IP if the struct defines an IP() method that has access to it?"

    You could make the struct field unexported i.e. ip not IP, and then in the place you are using struct.IP, use struct.IP() instead.

    The second question is:

    "If you have structs such as foo, bar, spam and they all share common fields, why not use composition to deduplicate the definition of those shared fields."

    This would probably only work if you are really only after the data that's inside the struct, I would generally advocate for using interfaces in all cases.

    If you have the following structs:

    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
    }
    

    You could use a new struct to represent the fields they have in common, and anonymously compose that inside:

    type Inner struct {
        IP string
        A string 
        B string
    }
    
    type Foo struct {
        Inner
    }
    
    type Bar struct {
        Inner
    }
    
    type Spam struct {
        Inner
    }
    

    In the function call where you were using struct.IP(), accept an Inner and call it with struct.Inner. You will still have access to struct.IP even though IP is defined inside Inner.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料