Передача функций в качестве аргумента, когда функции имеют разные подписи

Я прочитал много ответов, но я не мог найти окончательного ответа на свой вопрос.

В Swift у меня есть 3 (или более) разных метода. Единственное, что у них общего, это тип возвращаемого значения, например.

A(a:String)->MyType
B(a:Int,b:String,c:AnyObject,d:Whatever)->MyType
C(a:Int,b:String,c:Other)->MyType

Мне нужно передать функции в качестве аргумента метода класса, например.

myClass.configureIOTDevice(configFile:String, functionToCall:A)

Затем внутри тела этого метода я хочу вызвать:

functionToCall()

Как видите, возникает проблема: как передать нужные аргументы для разных сигнатур?

Приветствуется любая помощь, совет и, почему бы и нет, тухлый помидор :-)


person Community    schedule 03.08.2017    source источник
comment
Кто предоставляет значения для аргументов? Их тоже можно передать? Может быть, в словаре?   -  person vacawama    schedule 03.08.2017
comment
@vacawama Конечно, я мог бы создать MyType перед его передачей, но мой вопрос был ... своего рода теоретическим вопросом ;-)   -  person    schedule 03.08.2017
comment
Вы можете обернуть свою функцию замыканием, которое берет словарь типа [String: Any], распаковывает его и вызывает вашу функцию. Затем вы передадите словарь и замыкание ([String: Any]) -> MyType в свою функцию, и она вызовет functionToCall(dict), когда придет время.   -  person vacawama    schedule 03.08.2017
comment
Я надеялся на perform и NSSelectorFromString, но они немного ограничены   -  person    schedule 03.08.2017


Ответы (1)


Вы можете пойти так

func getData( functionToCall : Any) {
    if let function = functionToCall as? ()-> Void {
        function()
    }
    else if let function = functionToCall as? (String, String) -> Int {
        let result = function("a","b")
    }
}
person Mohammad Sadiq    schedule 03.08.2017
comment
Вы уверены, что отвечаете на мой вопрос? - person ; 03.08.2017
comment
Да мужик. Что вы хотите? Должен ли я вставить именно ваш код. У вас есть функцияToCall, передайте ей любую подпись. Теперь в зависимости от того, какая подпись передана, вызовите ее. - person Mohammad Sadiq; 03.08.2017
comment
хорошо, спасибо, но я искал что-то другое, это решение может стать трудным в обслуживании (каждый раз, когда вы добавляете новую функцию, вы также должны настраивать эту функцию getData: я прав? Или я что-то упустил?) - person ; 03.08.2017
comment
Это лучшее, что мы можем сделать. Как видите, это будет обратный вызов. Итак, когда он вызывает fuctionToCall, ему нужно знать параметр, который будет передан в functionToCall. Верно? Теперь, если вы добавите другое определение функции, getData необходимо обновить, чтобы передать и вызвать правильный метод. Без этого было бы невозможно. Как вы можете вызывать functionToCall как functionToCall(), когда это должно быть funtionToCall(String, Int... и т.д.)?. - person Mohammad Sadiq; 03.08.2017
comment
Хорошо, как я уже сказал, я надеялся на какую-нибудь магию perform, NSSelectorFromString или отражение. - person ; 03.08.2017