swift – 如何检查Any值是否确认通用协议,例如IntegerType

是否可以检查值是否动态确认通用协议?

我想做这样的事情:

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吗?除非别无选择,否则最好避免任何事情.也许你可以将泛型进一步推向管道?

点赞