简体   繁体   中英

Understanding Enums with Functions as Associated Values in Swift

I'm currently trying to understand the purpose and usage of enums holding a function/closure as an associated value. I do understand the purpose of enums holding values as follow...

enum Homework{
    case InProgress(Int, Int)
    case Complete
}

let load = Homework.InProgress(50, 100)

switch load {
    case .InProgress(let done, let total):
        print("\(done) out of \(total)")

    case .Complete:
        print("complete")
}

What I don't understand is the purpose of holding a closure as the value of an emum and how this would be used.

Can someone explain the main purpose where you would need to associate a closure to an enum?

Where and how would you use something like the following code? Can someone show a quick example?

enum SomeEnum{
    case ClosureOne (String, Double-> Double)
    case ClosureTwo (String, (Double, Double) ->Double)
}

Thanks

As @luk2302 notes, hunting for use cases of random types is, quite literally, "a solution in search of a problem." But perhaps it helps expand the mind about what is possible.

That said, embedding a function in an enum is just as useful as any other function parameter. For instance, you could use it to pass a recovery function in an error type:

enum Error: ErrorType {
    case Temporary(message: String, recovery: () -> Void)
    case Final(message: String)
}

func reconnect() {}

let err = Error.Temporary(
    message: "Network down",
    recovery: { reconnect() }
)

switch err {
case let .Temporary(message, recovery):
    print(message)
    recovery()
case let .Final(message):
    print(message)
    fatalError()
}

Or you could pass "how to convert to the next state" in any state machine (which is a very common use for enums).

enum State {
    case Login(next: (password: String) -> State)
    case Connecting(next: (Connection) -> State)
    case Connected(next: (Connection) -> State)
    case Disconnected(next: () -> State)
}

That would allow each state conversion to directly control the next state conversion, which in some cases is nicer than making all that logic centralized (especially if legal transitions is path-depenedent).

But again, as @luk2302 says, function values are just values. It would be a very unfortunate special case if enums could contain any value but functions.

I think when you want for instance multiply, add etc. by a certain number you could use enums with closures. This may not be the best example and of course it is NOT the only solution but I think it could be a case to associate a closure to an enum.

enum Operation{
    case AddBy (String, Double-> Double)
    case MultiplyBy (String, Double-> Double)
}


let multiplyByThree = Operation.MultiplyBy("Multiply", {(let num)-> Double in return num * 3})
let AddByThree = Operation.AddBy("Add", {(let num)-> Double in return num + 3})

switch multiplyByThree{

    case .MultiplyBy(let operation, let byNumber):

        print("\(operation) by Three =  \(byNumber(10))")

    case .AddBy(let operation, let byNumber):
        print("\(operation) by Three = \(byNumber(10))")
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM