Interface Literals

1,014 views
Skip to first unread message

Josh Smith

unread,
Feb 24, 2011, 10:54:13 AM2/24/11
to golang-nuts
So here's an example of what I am doing:

type FloatValue struct {
Get func() float32
Set func(f float 32)
}

func main () {
var value float32

fv := FloatValue {
func() float32 {
return value
},

func(f float32) {
value = f
}
}

fv.Set(42)
}

And I was thinking, it would be more useful to be able to do this:

type FloatValue interface {
Get () float32
Set (f float32)
}

func main () {
var value float32

fv := FloatValue {
func () float32 {
return value
},

func (f float32) {
value = f
}
}

fv.Set(42)
}

So, the closure context would act as the "receiver" of the interface
method calls (or it would just have a nil receiver if you like). I
think this borders on "method literals" that are specifically excluded
in the spec, and I've admittedly not thought through all the
implications or how useful it would be in general. I just know it
would be nice for me right now. Would anyone else have a use for this?

Russ Cox

unread,
Feb 25, 2011, 10:14:42 AM2/25/11
to Josh Smith, golang-nuts
you're conflating interfaces and implementations.
if you want to synthesize an implementation
with that generality, you can define a struct:

type FloatValueImpl struct {
get func() float32
set func(float32)
}

func (f FloatValueImpl) Get() float32 { return f.get() }
func (f FloatValueImpl) Set(g float32) { f.set(g) }

and then use

fv := FloatValue(FloatValueImpl{func..., func...})

but in the case you showed it would be easier to do

type floatValue float32

func (f *floatValue) Get() float32 { return *f }
func (f *floatValue) Set(g float32) { *f = g }

var value floatValue
fv := FloatValue(value)

kd...@arista.com

unread,
Apr 8, 2018, 2:35:06 PM4/8/18
to golang-nuts
Seven years later, I had the same idea as Js.

Before:

type intslice []int func (x intslice) Len() int { return len(x) } func (x intslice) Less(i, j int) bool { return x[i] < x[j] } func (x intslice) Swap(i, j int) { x[i], x[j] = x[j], x[i] } func main() { x := intslice{5, 1, 4, 2, 3} sort.Sort(x) log.Print(x) }
After:
func main() { x := []int{5, 1, 4, 2, 3} sort.Sort(sort.Interface{ Len() { return(len(x)) }, Less(i,j int) { return x[i] < x[j] }, Swap(i,j int) { x[i], x[j] = x[j], x[i] }, } log.Print(x) }

In my opinion, the latter is more elegant, because I don't have to change x's type to get the behavior I want, and because I can place the code that satisfies the interface where I use the interface.  Like Js indicated, the closure in which the interface literal is created would serve as the state for the interface literal's implementation.

Thanks,
   -Ken

Kenneth Duda
 

matthe...@gmail.com

unread,
Apr 8, 2018, 4:06:59 PM4/8/18
to golang-nuts
Here’s a way to do a similar thing now: https://play.golang.org/p/CtEYUo6MuqN

func main() {
    x
:= []int{5, 1, 4, 2, 3}

    sort
.Sort(ClosureSort(func() int { return (len(x)) },
        func
(i, j int) bool { return x[i] < x[j] },
        func
(i, j int) { x[i], x[j] = x[j], x[i] }))
    fmt
.Print(x)
}

The inside func could take a struct instead of multiple arguments to keep the interface method names. It would be a straightforward package that could probably be simplified from this playground example.

Matt
Reply all
Reply to author
Forward
0 new messages