dss087358 2019-09-09 12:34
浏览 141
已采纳

如何为指向不同结构的指针实现相同的功能?

Suppose I have a lot of different structs, but they all share a common field, such as "name". For example:

type foo struct {
    name string
    someOtherString string
    // Other fields
}

type bar struct {
    name string
    someNumber int
    // Other fields
}

Further on in the program, I repeatedly encounter the situation where I get pointers to these structs (so *foo, *bar, etc.) and need to perform operations depending on whether the pointer is nil or not, basically like so:

func workOnName(f *foo) interface{} {
    if (f == nil) {
        // Do lots of stuff
    } else {
        // Do lots of other stuff
    }
    // Do even more stuff
    return something
}

This function, which only uses name, is the same across all structs. If these were not pointers, I know I could write a common interface for each struct that returns the name and use that as the type. But with pointers, none of this has worked. Go either complains while compiling, or the nil check doesn't work and Go panics. I haven't found anything smarter than to copy/paste the exact same code for every struct that I have, so basically to implement all the functions:

func (f *foo) workOnName() interface{}
func (b *bar) workOnName() interface{}
func (h *ham) workOnName() interface{}
// And so on...

Is there a way to do this better, i.e. to only implement a simple function (or even better, no function at all) for all my structs and simply write the complicated stuff once, for all the structs?

Edit: Thank you to the answers so far, but simply using an interface of the type:

func (f foo) Name() string {
    return f.name
}

for some interface that provides Name() does not work, because the pointer is not recognized as nil. See this playground: https://play.golang.org/p/_d1qiZwnMe_f

  • 写回答

2条回答 默认 最新

  • dongyi6543 2019-09-09 12:41
    关注

    You can declare an interface which declares a function returning a name:

    type WithName interface {
        Name() string
    }
    

    In order to implement that interface, you types (foo, bar, etc) need to have that method - not just the field, the method.

    func (f foo) Name() string {
        return f.name
    }
    

    Then, workOnName needs to receive a reference of that interface:

    func workOnName(n WithName) interface{} {
        if (n == nil || reflect.ValueOf(n).isNil()) {
            // Do lots of stuff
        } else {
            // Do lots of other stuff
        }
        // Do even more stuff
        return something
    }
    

    Keep in mind that the parameter n WithName is always treated as a pointer, not an object value.

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

报告相同问题?

悬赏问题

  • ¥15 winform的chart曲线生成时有凸起
  • ¥15 msix packaging tool打包问题
  • ¥15 finalshell节点的搭建代码和那个端口代码教程
  • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据
  • ¥20 软件测试决策法疑问求解答