简体   繁体   English

在Swift中使用函数作为关联值了解枚举

[英]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. 我目前正在尝试了解将功能/闭包作为关联值的enums的目的和用法。 I do understand the purpose of enums holding values as follow... 我确实理解enums值的目的如下...

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. 我不了解将闭包作为emum的值的目的以及如何使用它。

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." 正如@ luk2302所指出的,从字面上看,寻找随机类型的用例实际上是“一种解决问题的解决方案”。 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. 但是,正如@ luk2302所说,函数值只是值。 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))")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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