In Go, is there a way to satisfy an interface anonymously? It doesn't seem like there is, but this was my best attempt.
(In the Playground)
package main import "fmt" type Thing interface { Item() float64 SetItem(float64) } func newThing() Thing { item := 0.0 return struct { Item (func() float64) SetItem (func(float64)) }{ Item: func() float64 { return item }, SetItem: func(x float64) { item = x }, } } func main() { thing := newThing() fmt.Println("Hello, playground") fmt.Println(thing) }
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With