Swift中的函数数组

时间:2014-06-25 21:32:02

标签: swift swift-playground

如何将一组函数存储在稍后在数组中回调,就像在JavaScript中一样? Any和AnyObject类型不能保存具有不同类型的方法签名的函数。

5 个答案:

答案 0 :(得分:20)

您可以使用枚举将各种函数放入数组中,然后使用开关提取函数。

    enum MyFuncs {
        case Arity0 ( Void -> Void )
        case Arity2 ( (Int, String) -> Void)
    }

    func someFunc(n:Int, S:String) { }
    func boringFunc() {}
    var funcs = Array<MyFuncs>()
    funcs.append(MyFuncs.Arity0(boringFunc))
    funcs.append( MyFuncs.Arity2(someFunc))

    for f in funcs {
        switch f {
        case let .Arity0(f):
            f()  // call the function with no arguments
        case let .Arity2(f):
            f(2,"fred") // call the function with two args
        }
    }

答案 1 :(得分:8)

注意:这个答案适用于Swift 1.0及更低版本。

具有不同参数和返回类型的函数具有不同的类型,因此它们不能一起存储在数组中。它们也不符合Any或AnyObject协议。

如果你有相同参数的函数,你可以解决这个问题。即使下面的函数返回Double和Int的元组,它们都可以定义为() -> Any函数类型。

func func1 () -> Int {
    return 1
}
func func2 () -> (Double, Double){
    return (2, 3)
}
var a: () -> Int = func1
var b: () -> (Double, Double) = func2

var arr: Array< () -> Any> = [a, b]

答案 2 :(得分:5)

下面是一个包含数组和字典的示例。在Xcode 6.1(6A1046a)中测试并使用。请注意,必须首先解开字典中的函数。

然而,当函数具有不同的参数或返回类型时,这种技术会分崩离析,原因在于康纳在他的回答中解释的原因。

class MyViewController: UIViewController
{
    let arrayOfFunctions = [function1, function2]

    let dictionaryOfFunctions = [
        "function1": function1,
        "function2": function2
    ]

    func function1() {
        NSLog("function1")
    }

    func function2() {
        NSLog("function2")
    }

    override func viewDidLoad()
    {
        let fn1 = arrayOfFunctions[0]
        fn1(self)()

        let fn2 = dictionaryOfFunctions["function2"]
        fn2!(self)()
    }
}

答案 3 :(得分:3)

从Swift 1.1开始,所有函数类型都符合Any,因此您可以在Any数组中保存函数。

func foo (str: String) -> Int {
    return 1
}
func bar () -> (Double, Double){
    return (2, 3)
}
var a: Any = foo
var b: Any = bar

var arr: Any = [a, b]

答案 4 :(得分:0)

按需调用存储在数组中的函数的更简单方法,使用参数的一个简单解决方法是使 dict args 并在函数内部使用它。

var args = [ "a" :  1, "b" : 2 ]
var requestQueue : [() -> Void] = []

func a() -> Void  {
    let param = args["a"]
    print(param!)
}

func b() -> Void {
    let param = args["b"]
    print(param!)
}

requestQueue.append(a)
requestQueue.append(b)

for item in requestQueue {
    item() //calling the functions
}