Anonymous interface implementation in Golang

Go uses method sets to declare which methods belong to a type. There is only one way to declare functions with receiver types (methods):

func (v T) methodName(...) ... { }

Since nested functions are forbidden, there is no way to define a method set on anonymous structs.

The second thing that will not allow this is that methods are read-only. Method values were introduced to allow to pass methods around and use them in goroutines but not to manipulate the method set.

What you can do instead is to provide a ProtoThing and refer to underlying implementations of your anonymous struct (on play):

type ProtoThing struct { 
    itemMethod func() float64
    setItemMethod func(float64)
}

func (t ProtoThing) Item() float64 { return t.itemMethod() }
func (t ProtoThing) SetItem(x float64) { t.setItemMethod(x) }

// ...

t := struct { ProtoThing }{}

t.itemMethod = func() float64 { return 2.0 }
t.setItemMethod = func(x float64) { item = x }

This works because by embedding ProtoThing the method set is inherited. Thus the anonymous struct also satisfies the Thing interface.


Here's neat way to satisfy an interface with an anonymous function.

type Thinger interface {
    DoThing()
}

type DoThingWith func()

// Satisfy Thinger interface.
// So we can now pass an anonymous function using DoThingWith, 
// which implements Thinger.
func (thing DoThingWith) DoThing() {
    // delegate to the anonymous function
    thing()
}

type App struct {
}

func (a App) DoThing(f Thinger) {
    f.DoThing()
}


//...Somewhere else in your code:
app := App{}

// Here we use an anonymous function which satisfies the interface
// The trick here is to convert the anonymous function to the DoThingWith type
// which delegates to the anonymous function

app.DoThing(DoThingWith(func() {
    fmt.Println("Hey interface, are you satisfied?")
}))

Playground: https://play.golang.org/p/k8_X9g2NYc

nb, it looks like HandlerFunc in http package uses this pattern: https://golang.org/pkg/net/http/#HandlerFunc

edit: Changed type DoThing to DoThingWith for clarity. Updated playground


You can not instantiate a struct with methods, they need to be declared as functions, but in Go functions are "first class citizens", so they can be field values just like in JavaScript (but typed).

You can make a generic struct that accepts func fields to implement the interface:

package main

import "fmt"

type Thing interface {
    Item() float64
    SetItem(float64)
}

// Implements Thing interface
type thingImpl struct {
    item    func() float64
    setItem func(float64)
}
func (i thingImpl) Item() float64     { return i.item() }
func (i thingImpl) SetItem(v float64) { i.setItem(v) }

func newThing() Thing {
    item := 0.0
    return thingImpl{
        item:    func() float64 { return item },
        setItem: func(x float64) { item = x },
    }
}

func main() {
    thing := newThing()
    fmt.Println("Hello, playground")
    fmt.Println(thing)
}