I'm trying to implement a linked list in golang. And I want the linked list to be able to store any type upon which equality testing can be performed.
Like say if there is,
type SimpleType struct {
int
}
s := SimpleType{3}
m := SimpleType{4}
I want to be able to do something like,
if s == m {}
or if s < m
and other equality testing.
I know I can accomplish this using interfaces. Like say, I can create an interface that has a comparison function and make the linked list only accept values that have the interface type.
But I was wondering if there was a better, more idiomatic way of doing it in Golang.
Like say, is it possible to directly use the relational operators <
, >
, ==
and co?
Or if that is not possible, is there a much better way using interfaces itself?
Thanks
I would say you should combine container/list
with ideas from sort.Interface
.
Basically, in your package mylist
you'd define something like:
type ListItem struct {
...
}
type Interface interface {
func Less(a, b *ListItem) bool
func Equal(a, b *ListItem) bool
}
(func Greater(a, b *ListItem) bool
is not needed because it's just !Less(a, b)
; same applies to NotEqual()
) …and then implement sorting function on your list which would require the caller to provide an implementation of Interface
to use by your algorythm—just like sort.Sort()
does.
To implement that you'd define
func Sort(head *ListElement, comp Interface) *ListElement
which would take the list's head, sort it using the provided comparator and return the head of the sorted list. The client would be required to provide a comparator, like with
import "github.com/Jay/mylist"
...
type Foo struct {
...
Id int // used for comparisons
...
}
type FooComp struct{}
func (FooComp) Less(a, b *mylist.ListItem) bool {
fa, fb := a.Value().(Foo), b.Value().(Foo)
return fa.Id < fb.Id
}
func (FooComp) Equal(a, b *mylist.ListItem) bool {
fa, fb := a.Value().(Foo), b.Value().(Foo)
return fa.Id == fb.Id
}
data := mylist.New()
head := mylist.PushBack(Foo{...})
// ... add more elements here
// Now sort the list using the comparator
head := mylist.Sort(head, FooComp{})
Here, the client code defines its own type, Foo
, to be stored in your list, and a comparator for it, FooComp
to be used for sorting by your implementation.