很可能我只是做错了。我正在尝试在 Swift 中创建一个 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?
,并且它“期望类型名称或协议(protocol)组合限制 T”
。”
现在我明白这意味着什么了。编译器告诉我函数类型不适合用作泛型类型约束。如果属实,这真是一个耻辱。我真正喜欢 Swift 的原因之一是,在可空性方面,它不会犯下 fork 类型系统的罪过。但当涉及到函数类型时,它似乎确实将类型系统分成了两部分。他们受到不同的对待。这意味着围绕函数类型编写高度通用的代码即使不是不可能,也会变得非常困难。
我当然可以写这个,但这对于我的口味来说不够通用:
func coalesce(values: [@autoclosure () -> Any?]) -> Any?
有人知道如何使用SequenceType
实现这样的事情吗?我正在考虑向 Apple 提交有关此问题的错误。
最佳答案
在这种情况下,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
}
关于generics - 无法在 Swift 中使用函数类型作为泛型类型约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27062862/