Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a case to an existing enum with a protocol

I want to create a protocol that enforces a certain case on all enums conforming to this protocol.

For example, if I have a enum like this:

enum Foo{
    case bar(baz: String)
    case baz(bar: String)
}

I want to extend it with a protocol that adds another case:

case Fuzz(Int)

Is this possible?

like image 380
cfischer Avatar asked Sep 11 '25 09:09

cfischer


1 Answers

Design

The work around is to use a struct with static variables.

Note: This is what is done in Swift 3 for Notification.Name

Below is an implementation on Swift 3

Struct:

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

protocol CoolCar {

}

extension CoolCar {

    static var Yellow : Car {

        return Car(rawValue: "Yellow")
    }
}

extension Car : CoolCar {

}

Invoking

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")
}

Note:

Please note this approach is not a substitute for enum, use this only when the values are not known at compile time.

like image 80
user1046037 Avatar answered Sep 13 '25 05:09

user1046037