可以修改其他包中定义的类型的方法集吗?

Der*_*ang -1 logging go

内置的loglog.Logger不提供ErrorWarning方法,如Python.

所以我想Logger使用以下代码为内置类型编写一个:

func (l *Logger) Error(v interface{}) {
    info := fmt.Sprintf("ERROR: %v", v)
    l.Println(info)
}
Run Code Online (Sandbox Code Playgroud)

我把上面的代码放在一个文件morelog.go下面GOPATH/src/log.

main.go我写的:

logger := log.New(os.Stdout, "Test", 1)
logger.Error("Error in main.")
Run Code Online (Sandbox Code Playgroud)

当我跑步时go build,我得到:

./main.go:124: logger.Error undefined (type *log.Logger has no field or method Error)
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过定义一个新类型并在该类型上定义方法来实现类似的目标.但我认为如果我可以将方法直接添加到buit-in类型可能会更好.

Jer*_*all 5

这两个答案都是正确的,所以我会提出更多的选择.您无法在未定义的类型上定义方法.函数确实是你可以做到这一点的一种方法,但你也可以通过重新定义类型或包装类型来实现.

例如,如果您不关心拆分outfile并且只想修改日志行,那么您可以执行其中一个操作.

重新定义类型:

type MyLogger log.Logger

func (l MyLogger) Info(msg string, args ...interface{}) {
    log.Logger(l).Printf(msg, args...)
}

func (l MyLogger) Error(msg string, args ...interface{} {
    log.Logger(l).Printf("ERROR: " + msg, args...)
}
Run Code Online (Sandbox Code Playgroud)

或包裹类型:

type MyLogger struct {
  log.Logger
}

func (l MyLogger) Info(msg string, args ...interface{}) {
  l.Printf(msg, args...)
}

func (l MyLogger) Error(msg string, args ...interface{}) {
  l.Printf("ERROR: " + msg, args...)
}
Run Code Online (Sandbox Code Playgroud)

重新定义类型将限制您可以调用的方法集到您定义的方法集.如果不首先进行转换,您将无法重用*Printf方法.通过嵌入来包装类型将允许您调用*Printf方法并使用您自己的方法包装这些方法.您可以在每种情况的Info和Error方法的实现中查看此示例.