Pono
Pono

Reputation: 11776

Swift3 - how to call class or struct functions by name

As I come from a JS background this is how I'd call a function by name stored in a variable:

var obj = {
    foobar: function(param) {
        // do something
    }
};

var key = "foobar";

obj[key](123);

Now I would like to recreate this in Swift, for example:

struct obj = {
    func foobar(param) {
        // do something
    }
}

let key:String = "foobar"

obj[key](123)

The above code unfortunately gives Type 'obj.Type' has no subscript members

Is there any way to call functions by names in a Struct, Class or a Dictionary (if it's even possible to store functions in Dicts?)

EDIT - MORE CONTEXT:

I have a user-supplied array of things say:

let arr = ["apples", "oranges", "pears"]

but this array can be as long as 20 items. Based on each item of the array I need to perform certain action. So I iterate over the array:

for (key, _) in arr {
    if (key == "apples") {
        handleApples()
    }

    if (key == "oranges") {
        handleOranges()
    }

    // and so on...
}

Sure, I can have a function with a simple switch that would consist of 20 cases but that's far from ideal. What if my array grows to say 100 items?

I was hoping to achieve something similar to this:

for (key, _) in arr {
    myClass[key]()
}

Upvotes: 0

Views: 572

Answers (2)

Luca Angeletti
Luca Angeletti

Reputation: 59496

Is there any way to call functions by names in a Struct, Class or a Dictionary (if it's even possible to store functions in Dicts?)

Yes you can store a function into a dictionary

Let's define a function type

typealias FuncType = () -> ()

and 2 functions

func func0() {
    print("Apples")
}

func func1() {
    print("Oranges")
}

Now we can create a dictionary where the key is String and the value is FuncType

let dict : [String:FuncType] = [
    "Apples" : func0,
    "Oranges" : func1
]

And of course we can invoke a function stored into the dictionary

dict["Apples"]?() // prints "Apples"

Upvotes: 5

ThePringle
ThePringle

Reputation: 196

I think this might be what you're looking for:

var obj: [String: Int] = {
  // do something, like call foobar(param) that's defined outside of the variable
  // or just manipulate data directly in here

  return ["foobar": 123]
  // or whatever dictionary you want that matches the type you defined for obj
}()

Kind of tough to give you a better answer without you posting the kind of output or behavior you're looking for.

Upvotes: 1

Related Questions