1

How can I pass a dynamic array struct as parameter in golang

For e.g

type Dog {
  Name string 
}

type Cat {
  Name uint
}

I want a function which takes array of either cat or dog as an argument and loop through the array in the function . Below is function of what I wanna achive

func (array of either cats or dogs ){

    for _ , item := range (array of either cats or dogs) {

   }  
 }
3
  • 3
    func F(slice ...interface{}) takes slice of anything, you can limit the "anything" with an interface that has more than 0 methods. Commented May 24, 2020 at 15:02
  • You can try the way @mkopriva suggested play.golang.com/p/XcdXSs5UrfK Commented May 24, 2020 at 16:04
  • Note that because a dog's name is a string, and a cat's name is a uint, you need entirely different code to actually work with the animal's name. So making one function that deals with both kinds of animals is probably the wrong way to go. Commented May 24, 2020 at 23:50

2 Answers 2

1

I am assuming you mean

type Dog struct{
  Name string 
}

type Cat struct{
  Name uint
}

Your function should accept interface{} as an argument, so you are free to send either Dog or Cat or whatever you want as an argument. But after accepting the data you need to apply Type assertion inside the function to extract the specific data type in order to loop over it as you can't loop over the interface.

x := args.(type) // x will contain the name of the data type store inside the interface{}

Or you could use

x := i.(Dog) //if you're absolutely sure that the data type is Dog

x, ok := i.(Cat) //If you're not sure and want to avoid runtime panic

Please read the Go Tour examples to learn more about type assertions.

Edit: In the comments @mkopriva suggested func F(slice ...interface{}), so you need to convert the slice of Dog or Cat to slice of interface{} for that function signature to work. You will have manually to add/append each element in the Cat or Dog slice to an interface{} slice to convert from slice of Cat or Dog to slice of interface{} slice.

Sign up to request clarification or add additional context in comments.

2 Comments

I want to send array of either cat or dog and loop through them in function
I have edited my answer so that my example shows type assertion for slice. Using interface{} means you can send any data type as an argument, but if it's an array then you need to apply type assertion to extract the underlying data and then loop over the slice. You could use if-else statement to handle the conversion of the two data type.
1

interface{} is one way to go, as mentioned in Answers.

I find the other interfaces also useful:


import (
    "fmt"
)

type Pet interface{}

type Dog struct {
    Pet
    Name string
}

type Cat struct {
    Pet
    Name uint
}

func listPets(pets []Pet) {
    for _, pet := range pets {
        fmt.Println(pet)
    }
}

func main() {
    pets := []Pet{Dog{Name: "Rex"}, Dog{Name: "Boss"}, Cat{Name: 394}}
    listPets(pets)
}

https://play.golang.org/p/uSiYmcrSuqJ

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.