一般来说,当在协议的上下文中覆盖泛型时,泛型类型持有者被视为可由
associatedtype
协议的一部分。在您的示例中,这将是
SectionIdentifierEnum
,它充当受约束对象的占位符
SectionIdenfierEnum
但是,它本身不是协议,因此不能将其用作泛型方法中的类型约束。你
可以
但是,请将其用作
test(...)
Swift 3.1
现在,目前(Swift 3.1),您不能将复杂的类型约束添加到
关联类型
但是,您可以提供仅适用于以下情况的默认实现:
Self
派生自
UIViewController
并实现
RequiresEnum
通过设置
截面标识
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)
上面,默认实现
仅在以下情况下可用
截面标识
等于混凝土类型
RequireEnumDefault
自己
派生自
UIViewController
截面标识
是
一串
已键入
,则相应地修改扩展的类型约束:
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)
}
}
enum EnumWithStringRawValue: String {
case foo
}
class MyViewController : UIViewController, RequiresEnum {
typealias SectionIdentifierEnum = EnumWithStringRawValue
}
let foo = MyViewController()
foo.test(identifier: EnumWithStringRawValue.foo)
一旦Swift 4发布,您将能够向
:s,根据Swift evolution提案的实施:
// 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)
同样,修改对默认实现的约束
测试(…)
不仅如此
截面标识
等于
要求默认值
(但对于任何枚举:在这种情况下,我们知道此类枚举将始终具有一个
一串
,由于
关联类型
protocol RequiresEnum: class {
associatedtype SectionIdentifierEnum: RawRepresentable
where SectionIdentifierEnum.RawValue == String
func test(identifier: SectionIdentifierEnum)
}
enum RequiresEnumDefault: String {
case `default`
}
extension RequiresEnum where Self: UIViewController {
func test(identifier: SectionIdentifierEnum) {
print(identifier.rawValue)
}
}
enum EnumWithStringRawValue: String {
case foo
}
class MyViewController : UIViewController, RequiresEnum {
typealias SectionIdentifierEnum = EnumWithStringRawValue
}
let foo = MyViewController()
foo.test(identifier: EnumWithStringRawValue.foo)