26

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

4

5 回答 5

28

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

    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
        }
    }
于 2014-06-27T08:39:26.860 回答
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]
于 2014-06-25T23:03:01.733 回答
7

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

然而,当函数具有不同的参数或返回类型时,这种技术确实会崩溃,原因由 connor 在他的回答中解释。

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)()
    }
}
于 2014-10-17T01:14:32.357 回答
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]
于 2014-10-19T14:02:11.883 回答
0

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

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
}
于 2021-07-02T09:46:10.587 回答