3

I am new to Golang, after I took a tour of A Tour of Go, I'm trying to make my own thing.

What I want

I want to put different types of the structs into a single slice (or struct?),

so I can use a for loop to pass each struct to a function.

For example

In PHP I can store my classes in an array and pass each of them to foobar() like this:

$classes = [$A, $B, $C, $D]; // $A, $B, $C, $D are classes (called `struct` in Golang). foreach ($classes as $class) foobar($class); 

What I tried

I tried to do the same in Golang, and I hope it looks like this:

A{B{}, C{}, D{}} 

Since I failed on using slice, I decided to use struct to hold my structs:

type A struct { B C D } type B struct { Date string } type C struct { Date string } type D struct { Date string } func main() { // Using reflect to loop the A struct: // http://stackoverflow.com/questions/18926303/iterate-through-a-struct-in-go v := reflect.ValueOf(A{}) for i := 0; i < v.NumField(); i++ { foobar(v.Field(i).Interface()) // Passing each struct to the `foobar()` function } } 

But it seems like I'm actually doing embedding instead of storing them, any suggestions please?

1 Answer 1

8

I think interface{} is what you're after. For example like this:

type A struct { data string } type B struct { data int } func printData(s interface{}) { switch s.(type) { case A: fmt.Printf("A: %s\n", s.(A).data) case B: fmt.Printf("B: %d\n", s.(B).data) } } func main() { classes := []interface{}{A{data: "first"}, B{data: 2}, A{data: "third"}} for _, c := range classes { printData(c) } } 

This is probably as close as you can get to "duck typing" in go.

Though if your structs are really that similar, you might better off defining a common interface instead and implementing that interface for each struct. Here is same example using interfaces:

type DataGetter interface { getDate() string } type A struct { data string } func (a A) getDate() string { return a.data } type B struct { data int } func (b B) getDate() string { return fmt.Sprintf("%d", b.data) } func printData(s DataGetter) { fmt.Printf("%s\n", s.getDate()) } func main() { classes := []DataGetter{A{data: "first"}, B{data: 2}, A{data: "third"}} for _, c := range classes { printData(c) } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.