Extending Interfaces in Go

David picture David · Dec 13, 2013 · Viewed 8.9k times · Source

Fairly new to go. I'm trying to modify this go scribe server implementation:

https://github.com/samuel/go-thrift/blob/master/examples/scribe_server/main.go

I'd like to pass a channel to the Log() func so I can pass scribe data to a separate go routine but I'm not sure how to modify scribe/thrift.go to extend the log interface to be

Log(messages []*scribe.LogEntry, counts chan string)  

(or whether this is even needed and if there is some way to extend the interface without messing with the original library).

Answer

nemo picture nemo · Dec 13, 2013

You can't modify or extend an already declared interface, you can only create a new one, possibly extending the old one. But you cannot re-declare methods in the interface.

This means that what you want to do (modify the Scribe interface so that its Log method has a different signature) is not possible.

What you can do is to have a type which holds your channel and embeds the structure you want to extend.

Example:

type Scribe interface {
    Log(Messages []*LogEntry) (ResultCode, error)
}

type ModifiedScribe struct {
    Scribe
    counts chan string
}

func (m *ModifiedScribe) Log(Messages []*LogEntry) (ResultCode, error) {
    // do something with m.counts

    // call embedded implementation's Log message
    return m.Scribe.Log(Messages)
}

The example above defines a struct which embeds a Scribe and defines its own Log method, utilizing the one of the embedded Scribe. This struct can be used wherever a Scribe is expected (as it implements the Scribe interface) but holds your additional channel.