在Swift中不能使用函数类型作为泛型类型约束

时间:2014-11-21 13:48:45

标签: generics swift

我很可能我做错了。我正在尝试在Swift中创建一个coalesce函数,这实际上就像学习语言一样。我想让它尽可能通用,所以我希望能够coalesce任何SequenceType。以下是我所拥有的重载:

func coalesce(S: SequenceType, T: @autoclosure () -> Any? where S.Generator.Element == T>(values: S) -> Any? {
    for value: () -> Any? in values {
        if let found = value() {
            return found
        }
    }
    return nil
}

func coalesce(values: @autoclosure () -> Any?...) -> Any? {
    return coalesce(values)
}

编译器告诉我,T不能转换为() -> Any?,并且它“预期类型名称或协议组成限制T。”

现在,我理解这意味着什么。编译器告诉我函数类型不适合用作泛型类型约束。如果是,那么这是真正的耻辱。我真正喜欢Swift的一个原因是,它不会犯到在可空性方面具有分叉类型系统的罪过。但是当涉及到函数类型时,它似乎 分叉类型系统。他们受到不同的待遇。这意味着围绕函数类型编写高度通用的代码变得非常困难,如果不是不可能的话。

我当然可以写这个,但这不符合我的口味:

func coalesce(values: [@autoclosure () -> Any?]) -> Any?

任何人都知道如何使用SequenceType来实现这样的目标?我正在考虑向Apple提交有关此问题的错误。

1 个答案:

答案 0 :(得分:1)

在这种情况下,typealias可以解决问题。

typealias AutoclosuredOptionalAny = @autoclosure () -> Any?

func coalesce<S: SequenceType where S.Generator.Element == AutoclosuredOptionalAny>(values: S) -> Any? {
    for value: AutoclosuredOptionalAny in values {
        if let found = value() {
            return found
        }
    }
    return nil
}