我希望创建一个协议
,该协议将强制所有符合该协议
的枚举类型
遵循特定的命名规则。
例如,如果我有一个像这样的枚举类型
:
enum Foo{
case bar(baz: String)
case baz(bar: String)
}
我希望用一个协议
来扩展它,该协议会添加另一种情况:
case Fuzz(Int)
这可行吗?
解决方法是使用带有静态变量的 struct
。
注意:这就是在 Swift 3 中为 Notification.Name
所做的。
以下是在 Swift 3 上的实现:
struct Car : RawRepresentable, Equatable, Hashable, Comparable {
typealias RawValue = String
var rawValue: String
static let Red = Car(rawValue: "Red")
static let Blue = Car(rawValue: "Blue")
//MARK: Hashable
var hashValue: Int {
return rawValue.hashValue
}
//MARK: Comparable
public static func <(lhs: Car, rhs: Car) -> Bool {
return lhs.rawValue < rhs.rawValue
}
}
protocol CoolCar {
}
extension CoolCar {
static var Yellow : Car {
return Car(rawValue: "Yellow")
}
}
extension Car : CoolCar {
}
let c1 = Car.Red
switch c1 {
case Car.Red:
print("Car is red")
case Car.Blue:
print("Car is blue")
case Car.Yellow:
print("Car is yellow")
default:
print("Car is some other color")
}
if c1 == Car.Red {
print("Equal")
}
if Car.Red > Car.Blue {
print("Red is greater than Blue")
}
请注意,这种方法不能替代enum
,仅在编译时不知道值的情况下使用。
不行,因为你不能在enum
之外声明case
。
扩展
可以添加一个嵌套的 枚举
,如下所示:enum Plants {
enum Fruit {
case banana
}
}
extension Plants {
enum Vegetables {
case potato
}
}
以你的例子为例:
enum Foo {
case bar(baz: String)
case baz(bar: String)
}
case
中:enum FooExtended {
case foo(Foo) // <-- Here will live your instances of `Foo`
case fuzz(Int)
}
通过这种解决方案,访问与类型相关的“隐藏”用例变得更加费力。但是在某些应用程序中,这种简化实际上可能是有益的。
另一种选择是重新创建并扩展它,同时有一种方法将Foo
转换为扩展的enum
FooExtended
(例如使用自定义init
):
enum FooExtended {
case bar(baz: String)
case baz(bar: String)
case fuzz(Int)
init(withFoo foo: Foo) {
switch foo {
case .bar(let baz):
self = .bar(baz: baz)
case .baz(let bar):
self = .baz(bar: bar)
}
}
}
也许有很多地方,其中一个或两个解决方案都没有意义,但我相信它们对某些人可能会有用(即使只是作为练习)。
protocol CoolCar
留空,然后再去扩展它呢? - Marty