如何检查 Any 值是否确认通用协议,例如整数类型
How can I check whether an Any value confirms a generic protocol, e.g. IntegerType
是否可以检查一个值以动态确认通用协议?
我想做这样的事情:
import func Darwin.atoll
func anyToInt(a: Any) -> IntMax {
if let v = a as? IntegerType { // error!!
return v.toIntMax()
} else {
return atoll("\(a)")
}
}
这会导致编译错误并显示消息 "error: protocol 'IntegerType' can only be used as a generic constraint ..."。
如果我使用正确的静态类型,我会通过类型参数约束使用重载:
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 Any
可能会支持。只能取出显式包含的类型:
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 { [=10=] as Printable }
// (is there a cleaner syntax than this?)
其次,您不能实例化具有关联类型的协议。您只能将它们用作通用约束。 Printable
的示例之所以有效,是因为它没有关联类型。有关原因的解释,请参阅 this answer。所以即使转换 Any
可以在协议上工作,你也不能将它转换为 IntegerType
.
但是你确定你必须在这里使用Any
吗? Any
真的最好避免,除非别无选择。也许您可以将仿制药进一步推向管道?
是否可以检查一个值以动态确认通用协议?
我想做这样的事情:
import func Darwin.atoll
func anyToInt(a: Any) -> IntMax {
if let v = a as? IntegerType { // error!!
return v.toIntMax()
} else {
return atoll("\(a)")
}
}
这会导致编译错误并显示消息 "error: protocol 'IntegerType' can only be used as a generic constraint ..."。
如果我使用正确的静态类型,我会通过类型参数约束使用重载:
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 Any
可能会支持。只能取出显式包含的类型:
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 { [=10=] as Printable }
// (is there a cleaner syntax than this?)
其次,您不能实例化具有关联类型的协议。您只能将它们用作通用约束。 Printable
的示例之所以有效,是因为它没有关联类型。有关原因的解释,请参阅 this answer。所以即使转换 Any
可以在协议上工作,你也不能将它转换为 IntegerType
.
但是你确定你必须在这里使用Any
吗? Any
真的最好避免,除非别无选择。也许您可以将仿制药进一步推向管道?