Search code examples
swiftenumsclosuresenumeration

Can a Swift enum have a function/closure as a raw value?


I know an enum can have a closure as an associated value, such as:

enum SomeEnum {
    case closureOne (String, Double -> Double)
    case closureTwo (String, (Double, Double) -> Double)
}

But, can an enum have a closure as a raw value? For instance, does something like this work?

enum someEnum: () -> Void {
    case closureOne = doSomething
    case closureTwo  = doSomethingElse
}

where

let doSomething = {
    // Do something here.
}

let doSomethingElse {
    // Do something else here.
}

Solution

  • It's not as straight forward, but you could use OptionSet, see this page:

    Unlike enumerations, option sets provide a nonfailable init(rawValue:) initializer to convert from a raw value, because option sets don’t have an enumerated list of all possible cases. Option set values have a one-to-one correspondence with their associated raw values.

    Could be something like this:

    func doSomething() {}
    func doSomethingElse() {}
    
    struct MyClosures: OptionSet {
    
        static let closureOne = MyClosures(rawValue: doSomething)
        static let closureTwo = MyClosures(rawValue: doSomethingElse)
    
        let rawValue: () -> Void
    
        init(rawValue: @escaping () -> Void) {
            self.rawValue = rawValue
        }
    
        init() {
            rawValue = {}
        }
    
        mutating func formUnion(_ other: __owned MyClosures) {
            // whatever makes sense for your case
        }
    
        mutating func formIntersection(_ other: MyClosures) {
            // whatever makes sense for your case
        }
    
        mutating func formSymmetricDifference(_ other: __owned MyClosures) {
            // whatever makes sense for your case
        }
    
        static func == (lhs: MyClosures, rhs: MyClosures) -> Bool {
            // whatever makes sense for your case
            return false
        }
    }
    

    And so you can use it as:

    let myClosures: MyClosures = [ .closureOne, .closureTwo ]
    

    HOWEVER looking at your explanation in the comment:

    So I'm trying to find the most efficient way to run a function given the state of a variable.

    I think what you actually want is some sort of state machine. Some examples are available here and here