Kobz
Kobz

Reputation: 469

Set a parameter as an interface or a list of interfaces

I'm pretty new to Go and there are some subtilities that I don't get yet

For instance, I have a function who may be called like this :

myVar.InitOperation("foo",Operator.EQUAL,"bar")
myVar.InitOperation("foo",Operator.INCLUDE,[]interface{}{"baz",1,"boo"})
myVar.InitOperation("foo",Operator.GREATER_THAN,1)

So I declared this function as :

func InitOperation(attr string, operator Operator, value interface{}){
    if operator.String() == "BAR"{
        doSomething(attr,operator,value)
    } else if (operator.String() == "INCLUDE" {
        doSomethingElse(attr,operator,value)
    }
    // And so on regarding to the case
}

The thing is that when I pass a string or an integer, it goes well but when I pass an array, it is parsed as a single element.

In my function doSomethingElse, I'm trying to iterate over values, and as you may guess, I have an error.

Fine, I'll just set values as []interface{} and not interface{}. Here, everything goes well but when I'm calling doSomething, it is parsed as [[myValue]] which is logical but not what I expect.

My question is, is there a way to pass either an []interface{} or interface{} who can be red as a value or an array of values regarding to the case ?

Thanks !

Upvotes: 3

Views: 73

Answers (1)

Sebastien C.
Sebastien C.

Reputation: 4833

You need a type assertion:

func InitOperation(attr string, operator Operator, value interface{}){
    if operator.String() == "BAR"{
        doSomething(attr,operator,value)
    } else if (operator.String() == "INCLUDE" {
        doSomethingElse(attr, operator, value.([]interface{}))
    }
    // And so on regarding to the case
}

func doSomethingElse(attr string, operator Operator, value []interface{}) {
    for _, v := range value {
        fmt.Println(v)
    }
}

Upvotes: 2

Related Questions