protocol RequiresEnum: class { associatedtype SectionIdentifierEnum: RawRepresentable // how this add restriction to RawValue == String func test<T: SectionIdentifierEnum>(identifier: T) where T.RawValue == String } enum RequiresEnumDefault: String { case `default` } extension RequiresEnum where Self: UIViewController,SectionIdentifierEnum.RawValue == String { typealias SectionIdentifierEnum = RequiresEnumDefault func test<T: SectionIdentifierEnum>(identifier: T) where T.RawValue == String { print(T.rawValue) } }
- ‘SectionIdentifierEnum’ is ambiguous for type lookup in this context
- ‘RawValue’ is not a member type of ‘T’
任何解决方案
解决方法
Swift 3.1
现在,当前(Swift 3.1),您无法将复杂的类型约束添加到关联类型.但是,您可以提供一个默认实现,仅适用于Self从UIViewController派生的情况,并通过将SectionIdentifierEnum类型设置为具体的RequiresEnumDefault类型来实现RequiresEnum协议.后者将确定关联的RawValue是此默认实现的String,因为具体RequiresEnumDefault类型的RawValue是String.
例如.:
// Swift 3.1 // --------- // Types that implement this protocol mustn't necessarily use a // `SectionIdentifierEnum` type where `SectionIdentifierEnum.RawValue` // is constrained to equal `String`. protocol RequiresEnum: class { associatedtype SectionIdentifierEnum: RawRepresentable func test(identifier: SectionIdentifierEnum) } enum RequiresEnumDefault: String { case `default` } // This extension,however,is only available for types that use // `RequiresEnumDefault ` as the concrete type of `SectionIdentifierEnum` // (in which case `SectionIdentifierEnum.RawValue` is `String`). extension RequiresEnum where Self: UIViewController,SectionIdentifierEnum == RequiresEnumDefault { func test(identifier: SectionIdentifierEnum) { print(identifier.rawValue) } } // Example usage. class MyViewController : UIViewController,RequiresEnum { typealias SectionIdentifierEnum = RequiresEnumDefault // ... } let foo = MyViewController() foo.test(identifier: RequiresEnumDefault.default) // prints "default" (using extension:s default implementation)
上面,test(…)的默认实现仅在SectionIdentifierEnum等于具体类型RequireEnumDefault(和Self派生自UIViewController …)时可用.如果您希望它仅在SectionIdentifierEnum是具有String类型RawValue的任何枚举时可用,则相应地修改扩展的类型约束:
protocol RequiresEnum: class { associatedtype SectionIdentifierEnum: RawRepresentable func test(identifier: SectionIdentifierEnum) } enum RequiresEnumDefault: String { case `default` } extension RequiresEnum where Self: UIViewController,SectionIdentifierEnum.RawValue == String { func test(identifier: SectionIdentifierEnum) { print(identifier.rawValue) } } // Example usage. enum EnumWithStringRawValue: String { case foo } class MyViewController : UIViewController,RequiresEnum { typealias SectionIdentifierEnum = EnumWithStringRawValue // ... } let foo = MyViewController() foo.test(identifier: EnumWithStringRawValue.foo) // prints "foo" (using extension:s default implementation)
一旦Swift 4发布,您将能够根据Swift evolution提案的实现向关联类型添加更复杂的约束:
> SE-0142: Permit where clauses to constrain associated types
// Swift 4 // ------- // Here,all types that implement this protocol must use a // `SectionIdentifierEnum` type where `SectionIdentifierEnum.RawValue` // is equal to `String`. protocol RequiresEnum: class { associatedtype SectionIdentifierEnum: RawRepresentable where SectionIdentifierEnum.RawValue == String func test(identifier: SectionIdentifierEnum) } enum RequiresEnumDefault: String { case `default` } // For the specific case where `SectionIdentifierEnum` equals // `RequiresEnumDefault` (and where `Self` derives from `UIViewController`),// this default implementation is readily available. extension RequiresEnum where Self: UIViewController,SectionIdentifierEnum == RequiresEnumDefault { func test(identifier: SectionIdentifierEnum) { print(identifier.rawValue) } } // Example usage. class MyViewController : UIViewController,RequiresEnum { typealias SectionIdentifierEnum = RequiresEnumDefault // ... } let foo = MyViewController() foo.test(identifier: RequiresEnumDefault.default) // prints "default" (using extension:s default implementation)
同样修改对test(…)的默认实现的约束,不仅仅是对于SectionIdentifierEnum等于RequiresEnumDefault的情况(但对于任何枚举:在这种情况下,我们知道这样的枚举将始终具有RawValue字符串,因为对协议定义中的associatedtype).
protocol RequiresEnum: class { associatedtype SectionIdentifierEnum: RawRepresentable where SectionIdentifierEnum.RawValue == String func test(identifier: SectionIdentifierEnum) } enum RequiresEnumDefault: String { case `default` } // From the constraint on the `RawValue` of `SectionIdentifierEnum` // above,we kNow that `RawValue` equals `String`. extension RequiresEnum where Self: UIViewController { func test(identifier: SectionIdentifierEnum) { print(identifier.rawValue) } } // Example usage. enum EnumWithStringRawValue: String { case foo } class MyViewController : UIViewController,RequiresEnum { typealias SectionIdentifierEnum = EnumWithStringRawValue // ... } let foo = MyViewController() foo.test(identifier: EnumWithStringRawValue.foo) // prints "foo" (using extension:s default implementation)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。