dsubq24666 2016-09-13 16:34
浏览 24
已采纳

编写可以操纵几种相似类型的函数

I'm trying to make several types that can call the same function to perform a few common operations, without needing to duplicate them for each type. Let's call those types handlers.

The idea is that I can have a CreateHandler, a ListHandler, etc, and a function that will do default operations for those handlers, let's say, set the "Success" field to true and call the "Execute" function on the handler. I keep those examples simple to make them easy to read, but in real case there would be way more common operations.

I've tried 3 different approaches, to no avail: using a base type and embed it, using an interface implemented by types and using an empty interface as parameter.

Base type embedded

package main

import "fmt"

type BaseHandler struct {
  Success bool
}

func ( handler *BaseHandler ) Init() {
  handler.Success = true
  handler.Execute()
}

func ( handler *BaseHandler ) Execute() {
}



// I will have many different types doing the same kind of work,
// with their own specific fields and functions
type MyHandler struct {
  BaseHandler
  Message string
}

func ( handler *MyHandler ) Execute() {
  fmt.Println( "I'm never called" )
}

func main() {
  handler := MyHandler{}
  handler.Init()
}

This won't work because the Execute function called is the one from BaseHandler, not from MyHandler. Same problem if the Init method has no receiver and takes a *BaseHandler as parameter.

interface implemented by types

package main

import "fmt"

type BaseHandler interface {
  Execute()
}

func Init( handler BaseHandler ) {
  handler.Success = true
  handler.Execute()
}

type MyHandler struct {
  Success bool
  Message string
}

func ( handler *MyHandler ) Execute() {
  fmt.Println( "I'm never called" )
}

func main() {
  handler := MyHandler{}
  Init( handler )
}

This will fail to compile because of first line of Init function, saying that the BaseHandler interface does not have a Success field.

empty interface as parameter

package main

import "fmt"

func Init( handler interface{} ) {
  handler.Success = true
  handler.Execute()
}


type MyHandler struct {
  Success bool
  Message string
}

func ( handler *MyHandler ) Execute() {
  fmt.Println( "I'm never called" )
}

func main() {
  handler := MyHandler{}
  Init( handler )
}

This will fail to compile on first line of Init saying that interface{} has no Success field. I can't do type assertion there, because it would mean listing all the types which can go there, and there may be a lot.

Question

So here is my question: how do you write shared code, that can set fields and call functions from similar types?

  • 写回答

3条回答 默认 最新

  • dqyat62284 2016-09-13 17:12
    关注

    handler.Success = true feels like it belongs within Execute. Thus, you could define an interface and make Init a function on this interface, while embedding the interface in "children":

    type Handler interface {
        Execute()
    }
    
    func Init(handler Handler) {
        handler.Execute()
    }
    
    type BaseHandler struct {
        Success bool
    }
    
    func (handler *BaseHandler) Execute() {
        handler.Success = true
        fmt.Println("success: true")
    }
    
    type MyHandler struct {
        Handler
        Message string
    }
    
    func (handler *MyHandler) Execute() {
        fmt.Println("I do some work before")
        handler.Handler.Execute()
        fmt.Println("I do some work after")
    }
    
    func main() {
        handler := &MyHandler{&BaseHandler{}, "foo"}
        Init(handler)
    }
    

    Playground: https://play.golang.org/p/iDo2BQ6N5D.

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

报告相同问题?

悬赏问题

  • ¥15 VFP如何使用阿里TTS实现文字转语音?
  • ¥100 需要跳转番茄畅听app的adb命令
  • ¥50 寻找一位有逆向游戏盾sdk 应用程序经验的技术
  • ¥15 请问有用MZmine处理 “Waters SYNAPT G2-Si QTOF质谱仪在MSE模式下采集的非靶向数据” 的分析教程吗
  • ¥50 opencv4nodejs 如何安装
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题