是否可以调用 Any 的 callAsFunction() 变量?

Is is possible to callAsFunction() variable that is Any?

最近遇到了创建函数数组的需求。不幸的是,Swift 语言没有为函数提供顶级类型,而是必须通过它们的特定签名 (...)->(...) 来声明它们。所以我尝试编写一个可以容纳任何函数的包装器,然后将其专门化以仅容纳具有 Void return 类型和任意数量参数的闭包。

struct AnyFunction {
    let function: Any
    init?(_ object: Any){
        switch String(describing: object){
            case let function where function == "(Function)":
                self.function = object
            default:
                return nil
        }
    }
    func callAsFunction(){
        self.function()
    }
}

随着我的进步,我发现这不是微不足道的,可能需要一些反省的技巧,但尽管我尝试过,但我还是没有找到解决方案。编译器消息:

error: cannot call value of non-function type 'Any'

那么,您将如何实现这个技巧,即定义一个可以包含任何函数类型的对象?

澄清: 我更喜欢定义如下内容:

typealias SelfSufficientClosure = (...)->Void
var a, b, c = 0
let funcs = FunctionSequence
    .init(with: {print("Hi!")}, {a in a + 3}, {b in b + 3}, { a,b in c = a + b})
for f in funcs { f() }

print([a, b, c])
//outputs 
//"Hi"
//3, 3, 6

PS这个问题与这个问题有关()

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

 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
        }
    }

函数是从输入到输出的映射。在你的例子中,你的输入是无效的(没有输入),你的输出也是无效的(没有输出)。所以那种函数就是() -> Void.

我们可以根据您的称呼方式判断这是正确的类型:

for f in funcs { f() }

您期望 f 是一个没有输入且 return 没有输出的函数,这正是 () -> Void 的定义。我们可以通过使用该类型(并清除一些语法错误)准确地获得您期望的输入和输出:

var a = 0, b = 0, c = 0

let funcs: [() -> Void] = [{print("Hi!")}, {a = a + 3}, { b = b + 3}, { c = a + b}]
for f in funcs { f() }

print(a, b, c, separator: ",")
//outputs
//Hi!
//3, 3, 6

当你写一个像 {a in a + 3} 这样的闭包时,这并不意味着 "capture a"(我相信你在期待)。这意味着 "This is a closure that accepts a parameter that will be called a (completely unrelated to the global variable of the same name) and returns that value plus 3." 如果那是你的意思,那么当你调用 f() 时,你需要传递一些东西并用 return 值做一些事情。