如何扩展现有类型以符合接口

时间:2020-09-07 04:56:07

标签: go

我已经使用以下方法定义了接口Logger

type Logger interface {
    Info(args ...interface{})
    Warn(args ...interface{})
    Error(args ...interface{})
}

现在,我想扩展log.Logger类型以符合此接口。由于log.Logger尚未定义这些方法,因此我需要实现它们。

我试图通过添加新方法来扩展它:

type LoggerImpl log.Logger

func (logger *LoggerImpl) Info(v ...interface{}) {
    logger.Println(v)
}

func (logger *LoggerImpl) Warn(v ...interface{}) {
    logger.Println(v)
}

func (logger *LoggerImpl) Error(v ...interface{}) {
    logger.Println(v)
}

但是当我收到一个错误消息logger.Println undefined (type *LoggerImpl has no field or method Println)时,这似乎是错误的方法。

我尝试过的另一个解决方案是嵌入类型,但这也会返回错误:

type LoggerImpl struct {
    log.Logger
}

func (logger *LoggerImpl) Info(v ...interface{}) {
    logger.Println(v)
}

func (logger *LoggerImpl) Warn(v ...interface{}) {
    logger.Println(v)
}

func (logger *LoggerImpl) Error(v ...interface{}) {
    logger.Println(v)
}

func initLogger() *LoggerImpl {
    logger := log.New(os.Stdout, "", log.Lshortfile)

    return logger
}

我在这里遇到的错误是从initLogger函数返回记录器时:cannot use logger (variable of type *log.Logger) as *LoggerImpl value in return statement

如何修改log.Logger类型以符合Logger界面?

1 个答案:

答案 0 :(得分:3)

您不能为在其他程序包中声明的类型定义方法。但是,您可以定义一个新类型,将旧类型嵌入到新类型中,并为新类型定义新方法:

type LoggerImpl struct {
   *log.Logger
}


func (logger *LoggerImpl) Error(v ...interface{}) {
    logger.Logger.Println(v)
}

func initLogger() *LoggerImpl {
    logger := &LoggerImpl{Logger:log.New(os.Stdout, "", log.Lshortfile)}

    return logger
}
...

以上,LoggerImpl包含为log.Logger声明的所有方法,以及您在此软件包中明确声明的方法。

通常:如果将类型嵌入另一个结构中,则封闭的结构将获取​​为嵌入式类型定义的所有方法。如果您从其他类型定义新类型,则新类型不会获得基本类型的任何方法。