このprotocol
に準拠するすべてのenums
に特定のケースを強制するprotocol
を作成したいと思います。
たとえば、次のようなenum
があるとします。
enum Foo{
case bar(baz: String)
case baz(bar: String)
}
別のケースを追加するprotocol
で拡張したい:
case Fuzz(Int)
これは可能ですか?
回避策は、struct
変数とともにstatic
を使用することです。
注:これはSwift for Notification.Name
以下はSwiftの実装です
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
の代替ではないことに注意してください。これは、コンパイル時に値が不明な場合にのみ使用してください。
いいえ、case
の外でenum
を宣言することはできないためです。
extension
は、次のようにネストされたenum
を追加できます。
enum Plants {
enum Fruit {
case banana
}
}
extension Plants {
enum Vegetables {
case potato
}
}
ここに誰かが役立つかもしれないいくつかの追加のテイクがあります:
あなたの例を使用して:
enum Foo {
case bar(baz: String)
case baz(bar: String)
}
あなた自身のcase
のenum
にそれを「ネスト」することを考えることができます:
enum FooExtended {
case foo(Foo) // <-- Here will live your instances of `Foo`
case fuzz(Int)
}
このソリューションでは、「非表示」のケースに関連付けられたタイプにアクセスするのがさらに面倒になります。しかし、この単純化は、特定のアプリケーションでは実際に有益な場合があります。
もう1つの方法は、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)
}
}
}
これらのソリューションのどちらか、または両方がまったく意味をなさないところがたくさんあるかもしれませんが、私はそれらがそこにいる誰かにとって便利であると確信しています(たとえ演習としても)。