我有2个从一个通用协议继承的协议
protocol IdentifierProtocol: Equatable, RawRepresentable {}
protocol A_IdentifierProtocol: IdentifierProtocol {}
protocol B_IdentifierProtocol: IdentifierProtocol {}
我希望使用函数进行拆分,但此代码会出错
extension UIClass {
func myFunc<I: IdentifierProtocol>(identifier: I) where I.RawValue == String {
if identifier is A_IdentifierProtocol { // <- Error
print("A")
}
if identifier is B_IdentifierProtocol { // <- Error
print("B")
}
}
}
错误:协议&#39; A_IdentifierProtocol&#39;只能用作通用约束,因为它具有Self或关联类型要求
我该如何解决这个问题?
答案 0 :(得分:0)
IdentifierProtocol
为RawRepresentable
,associatedType
。并且这样的协议不能使用&#34;就好像它是具体的类型&#34;。
这基本上就是编译错误所说的:
错误:协议&#39; A_IdentifierProtocol&#39;只能用作通用约束,因为它具有Self或关联类型要求
我建议您阅读有关错误的解释,而不是复制信息:https://stackoverflow.com/a/36350283/2378431
如果你想解决这个错误并仍然让代码工作没有任何明显的区别(从使用角度来看),你可以为每个X_IdentifierProtocol
定义单个方法,如下所示:
protocol IdentifierProtocol: Equatable, RawRepresentable {}
protocol A_IdentifierProtocol: IdentifierProtocol {}
protocol B_IdentifierProtocol: IdentifierProtocol {}
func myFunc<I: A_IdentifierProtocol>(identifier: I) where I.RawValue == String {
print("A: \(identifier.rawValue)")
}
func myFunc<I: B_IdentifierProtocol>(identifier: I) where I.RawValue == String {
print("B: \(identifier.rawValue)")
}
缺点是,对于每个X_IdentifierProtocol
,您需要提供一个方法实现,并且如果您希望基于IdentifierProtocol
拥有一段共享代码,则可能会引入一些代码重复。
另一种方法:如果您真的想要单一功能,则不能将IdentifierProtocol
与关联类型相关联。但是,您可以对泛型函数有多种类型约束,如下所示:
protocol IdentifierProtocol {}
protocol A_IdentifierProtocol: IdentifierProtocol {}
protocol B_IdentifierProtocol: IdentifierProtocol {}
func myFunc<I: IdentifierProtocol & Equatable & RawRepresentable>(identifier: I) where I.RawValue == String {
if identifier is A_IdentifierProtocol {
print("A: \(identifier.rawValue)")
}
if identifier is B_IdentifierProtocol {
print("A: \(identifier.rawValue)")
}
}
class MyClassA: A_IdentifierProtocol, RawRepresentable, Equatable {...}
class MyClassB: B_IdentifierProtocol, RawRepresentable, Equatable {...}
但即使这样也不完美,也不能完全满足您的要求。
底线是你无法用Swift 3完全达到你想要的效果。