是否可以检查值是否动态确认通用协议?
我想做这样的事情:
import func Darwin.atoll
func anyToInt(a: Any) -> IntMax {
if let v = a as? IntegerType { // error!!
return v.toIntMax()
} else {
return atoll("\(a)")
}
}
这使得编译错误消息“错误:协议’IntegerType’只能用作通用约束……”.
如果我使用了正确的静态类型,我将使用类型参数约束进行重载:
func anyToInt<T where T: IntegerType>(a: T) -> IntMax {
return a.toIntMax()
}
func anyToInt<T>(a: T) -> IntMax {
return atoll("\(a)")
}
不幸的是,在我的情况下,没有办法使用静态类型而不是Any.
最佳答案 你不能,原因有两个:
首先,你可以支持的can’t cast the contents of an Any
to a protocol.您只能获得包含的显式类型:
let i = 1
i as Printable // works
let a: Any = i
a as? Printable // doesn’t work
let p = a as Int as Printable // works
// or, if you don’t want to crash if a isn’t an Int
let p = (a as? Int).map { $0 as Printable }
// (is there a cleaner syntax than this?)
其次,您无法实例化具有关联类型的协议.您只能将它们用作通用约束.仅使用Printable的示例有效,因为它没有关联的类型.有关原因的说明,请参见this answer.因此,即使转换Any可以在协议上工作,也无法将其转换为IntegerType.
但你确定你必须在这里使用Any吗?除非别无选择,否则最好避免任何事情.也许你可以将泛型进一步推向管道?