我正在编写一个简单的库来协助常见的断言。
type Test interface {
Fatalf(string, ...interface{})
}
func IsTrue(statement bool, message string, test Test) {
if !statement {
test.Fatalf(message)
}
}
我注意到log
包实际上具有Fatalf(string, ...interface{})
的兼容实现,如果可以相应地调用IsTrue
方法,那就太棒了:
IsTrue(false, "false wasn't true", log)
但我收到错误use of package log not in selector
。有没有办法使用或包装一个包来使这个模式工作或者这是不可能的?
答案 0 :(得分:4)
你可以期待的最好的方法是将它包装在一个空白的结构中,如下所示:
type internalLog struct{}
func (il internalLog) Fatalf(s string, i ...interface{}) {
log.Fatalf(s, i...)
}
一般来说,由于包不是Go中的类型,因此无法满足任何要求。您必须将它们包装在另一种类型中,以便模拟它们满足界面。
编辑:
正如Caleb提到的(我忘记了),特定中的包log
具有函数New
,它返回一个* log.Logger,它将满足{{在你的情况下接口(以及大多数其他包级Test
函数)。但是,一般如果没有提供这样的类型,你必须如上所示包装包。
答案 1 :(得分:1)
我会使用log
创建一个可以覆盖的默认提供程序:
package main
import (
"log"
"os"
)
type TestLogger interface{
Fatalf(string, ...interface{})
}
var DefaultLogger TestLogger
func init() {
DefaultLogger = log.New(os.Stderr, "", log.LstdFlags)
}
func IsTrue(statement bool, message string) {
if !statement {
DefaultLogger.Fatalf(message)
}
}
func main() {
IsTrue(false, "MESSAGE")
}
如果有人在使用您的包裹,他们可以这样做:
type MyCustomImplementation struct {}
func (this MyCustomImplementation) Fatalf(msg string, args ... interface{}) {
// do whatever in here
}
some_package.DefaultLogger = MyCustomImplementation{}