首页 > 解决方案 > 功能序列中的任何问题或问题

问题描述

我遇到的问题是我需要创建一个可以调用的函数序列,但是遇到了一个问题,即即使一个函数是一等成员并且符合协议Any,下面的代码也不起作用。

struct FunctionSequence {

    var callbacks = [Any]() //how to restrict Any to only functions?

    init(with functions: Any...){
        self.callbacks = functions
    }

    func callAll(){
        for f in callbacks {
            f()
        }
    }
}

编译中断:

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

所以我向那些深谙 Swift 的人寻求帮助。PS我需要的结果如下:

var printer = FunctionSequence
    .init(with: {print("Hello,")}, {print("world!")})
printer.callbacks.insert({print("I hate you,")}, at: 1)
printer.callAll()
//outputs "Hello, I hate you, world!"

标签: swiftfunction

解决方案


没有通用的“函数类型”——具有不同参数或不同返回类型的函数是不同的类型。

在您的情况下,您显然想要一个类型的函数数组() -> Void,即不带参数且不返回值的函数:

struct FunctionSequence {

    var callbacks = [() -> Void]()

    init(with functions: (() -> Void)...){
        self.callbacks = functions
    }

    // ...
}

或者使用类型别名:

typealias SimpleFunction = () -> Void

struct FunctionSequence {

    var callbacks = [SimpleFunction]()

    init(with functions: SimpleFunction...){
        self.callbacks = functions
    }

    // ...
}

如果callbacks被定义为一个数组,Any那么你可以在其中放入任何东西:不带参数的函数,带一个整数的函数,...,整数,字符串,任何东西。

然后可以检查每个数组元素的特定签名,并相应地调用函数。例子:

struct FunctionSequence {

    var callbacks = [Any]()

    init(with functions: Any...){
        self.callbacks = functions
    }

    func callAll() {
        for f in callbacks {
            switch f {
            case let f0 as () -> Void:    f0()
            case let f1 as (Int) -> Void: f1(17)
            default: break // Other function signature, or not a function at all.
            }
        }
    }
}

let printer = FunctionSequence(with:
        { print("Hello,") },
        { (i: Int) in print(i)} )
printer.callAll()

推荐阅读