Question

I'm writing a simple library to assist with common assertions.

type Test interface {
    Fatalf(string, ...interface{})
}

func IsTrue(statement bool, message string, test Test) {
    if !statement {
       test.Fatalf(message)
    }
}

I noticed that the log package actually has a compatible implementation of Fatalf(string, ...interface{}) and it'd be great if the IsTrue method could be invoked accordingly:

IsTrue(false, "false wasn't true", log)

But I get the error use of package log not in selector. Is there any way to use or wrap a package to make this pattern work or is this not possible?

Was it helpful?

Solution

The best you can hope for is to wrap it in a blank struct like so:

type internalLog struct{}

func (il internalLog) Fatalf(s string, i ...interface{}) {
    log.Fatalf(s, i...)
}

In general, since packages are not types in Go, they cannot satisfy anything. You have to wrap them in another type in order to simulate them satisfying an interface.

Edit:

As Caleb mentions (and I forgot about), the package log in specific has the function New which returns a *log.Logger which will satisfy the Test interface in your case (as well as most other package-level log functions). However, in general if no such type is provided you must wrap the package like I showed above.

OTHER TIPS

I would make a default provider using log that can be overwritten:

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")
}

If someone was using your package they could do something like this:

type MyCustomImplementation struct {}

func (this MyCustomImplementation) Fatalf(msg string, args ... interface{}) {
    // do whatever in here
}

some_package.DefaultLogger = MyCustomImplementation{}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top