writing a generic Contains(slice, element)

6,803 views
Skip to first unread message

Taliesin

unread,
May 26, 2012, 6:42:14 PM5/26/12
to golang-nuts
Here is the closest I've got on my own:

package main

func Contains(list []interface{}, elem interface{}) bool {
for _, t := range list { if t == elem { return true } }
return false
}

func main() {
list := []interface{}{1,2,2,1,1,3}
println(Contains(list, 3))
println(Contains(list, 5))
}

That works fine, but I have to use slices of interface{}.

Is this the kind of problem that only proper generics can solve? Or
can I cheat in some way that strictly speaking violates type safety so
that any old type of slice will work?
Message has been deleted

Taliesin

unread,
May 26, 2012, 7:34:10 PM5/26/12
to golang-nuts
Thank you. I had no idea the built-in reflection was so powerful!

I'm going to play with it now (there goes the rest of my long
weekend...)

On May 26, 7:00 pm, Peter Thrun <peterth...@ymail.com> wrote:
> > Is this the kind of problem that only proper generics can solve? Or
> > can I cheat in some way that strictly speaking violates type safety so
> > that any old type of slice will work?
>
> You can use the reflect package.  Seehttp://play.golang.org/p/Wb4oB3OckI

Steven Blenkinsop

unread,
May 27, 2012, 12:39:23 AM5/27/12
to Taliesin, golang-nuts
On Sat, May 26, 2012 at 7:34 PM, Taliesin <tali...@gmail.com> wrote:
Thank you. I had no idea the built-in reflection was so powerful!

I'm going to play with it now (there goes the rest of my long
weekend...)

You might also consider, since it's such a simple function, just writing it when you need it. 

Robert Johnstone

unread,
May 27, 2012, 1:11:59 AM5/27/12
to golan...@googlegroups.com
No need to worry about every DRY violation...

Steven Blenkinsop

unread,
May 27, 2012, 2:33:12 AM5/27/12
to Robert Johnstone, golan...@googlegroups.com
On Sunday, May 27, 2012, Robert Johnstone wrote: 
No need to worry about every DRY violation...
The code is literally a for loop with a simple if statement in it. Next you'll tell me that calling functions gets a bit repetitive.

Robert Johnstone

unread,
May 29, 2012, 10:26:08 AM5/29/12
to golan...@googlegroups.com, Robert Johnstone
You are right, it is a small violation, but it is still a violation, notwithstanding your caricature of my previous pot.

Kyle Lemons

unread,
May 29, 2012, 12:47:24 PM5/29/12
to Robert Johnstone, golan...@googlegroups.com
On Sat, May 26, 2012 at 10:11 PM, Robert Johnstone <r.w.jo...@gmail.com> wrote:
No need to worry about every DRY violation...

Writing it generically is a waste.  Writing it once with a for loop is fine.  The third time you might want to move it into a type-specific Contains method.

Carlos Castillo

unread,
May 29, 2012, 5:30:07 PM5/29/12
to golan...@googlegroups.com, Robert Johnstone
Aside from being a waste, writing it generically is also very panic/error prone (http://play.golang.org/p/rs6kfvRD9M).

You get panics at runtime if you don't pass a slice as first argument, and you can easily not get the result you're looking for, since go considers values
of different types (in interface values) to never be equal. In both these cases, writing the for-range-if loop yourself will not have these problems because the code will not compile until the types are correct (no panics), and thus the comparison will work as expected.

Also it's much slower.

Depending on the implementation of Contains, you could get a run time panic, or never succeed in a case that seems to be obviously true (since the types actually don't match).
Reply all
Reply to author
Forward
0 new messages