How to pass arbitrary typed (int, string, etc) slices to a golang function?

183 views
Skip to first unread message

Lax Clarke

unread,
Sep 23, 2016, 12:13:04 AM9/23/16
to golang-nuts
How would someone create a function like len ?

func Len(s []interface{})   would not work because compiler complains of type mismatch if you call it with an integer slice (for example)

Thanks

Dave Cheney

unread,
Sep 23, 2016, 12:30:36 AM9/23/16
to golang-nuts
There are two ways, one is to use reflection, the other would be to use unsafe to convert the slice value into another structure then extract the length field.

Assuming that you could write a Len function as you specified, what would you do next? What problem are you trying to solve?

Fei Ding

unread,
Sep 23, 2016, 5:55:53 AM9/23/16
to golang-nuts

在 2016年9月23日星期五 UTC+8下午12:13:04,Lax Clarke写道:
How would someone create a function like len ?

func Len(s []interface{})   would not work because compiler complains of type mismatch if you call it with an integer slice (for example)

Thanks

[]interface{} is a concrete type, which is miss-match with []int{}. You may use interface{} as formal parameter but call the function with a []interface{}

package main

import "fmt"
import "reflect"

func Len(v interface{}) int {
var length int

switch reflect.TypeOf(v).Kind() {
// return the length of slice, use
// func (v Value) Len() int
case reflect.Slice:
length = reflect.ValueOf(v).Len()

// return the length of int, or whatever you want
case reflect.Int:

// ...
}

return length
}

type X struct {
a, b int
}

func main() {
a := []int{1,2,3} // a typed slice, all elements' type is concrete (int)
b := []interface{}{1, "11", 12.345, X{1, 2}} // still a typed slice, all elements' type is dynamic (interface)
fmt.Println(Len(a), Len(b))
}


Lax Clarke

unread,
Sep 24, 2016, 4:10:07 PM9/24/16
to golang-nuts


On Friday, September 23, 2016 at 12:30:36 AM UTC-4, Dave Cheney wrote:
There are two ways, one is to use reflection, the other would be to use unsafe to convert the slice value into another structure then extract the length field.

Assuming that you could write a Len function as you specified, what would you do next? What problem are you trying to solve?


Ok, I'm sorry for not stating actual problem.
I'm trying to remove duplicates from slices (of various types, strings, int, float is enough for now).
This requires me to create a map from that type to boolean, for example, as part of the algorithm.

I cannot figure out how to make such a function work for all types (note I'm coming from C++ and Java where I knew how to do this). 

Roberto Zanotto

unread,
Sep 24, 2016, 4:26:51 PM9/24/16
to golang-nuts

Roberto Zanotto

unread,
Sep 24, 2016, 4:54:34 PM9/24/16
to golang-nuts
If you don't care about preserving the order of the elements in the slice, you can do something like this:
https://play.golang.org/p/6QWxWH-Oj7

The functions I used are documented here: https://golang.org/pkg/reflect/
You may want to read this blog post about reflection: https://blog.golang.org/laws-of-reflection
Reflection is the only way to make the function generic.
If you need performance, you can write specialized functions for int, float, string and then use reflect to decide which one to call.
Reply all
Reply to author
Forward
0 new messages