在Swift中将函数理解为具有关联值的枚举

时间:2016-01-22 13:18:41

标签: swift enums closures

我目前正试图了解enums持有函数/闭包作为关联值的目的和用法。我确实理解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")
}

我不明白的是将封闭作为一个emum的价值以及如何使用它的目的。

有人可以解释您需要将闭包与枚举关联的主要目的吗?

您在何处以及如何使用以下代码?有人可以展示一个简单的例子吗?

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

由于

2 个答案:

答案 0 :(得分:2)

正如@ luk2302所指出的那样,搜索随机类型的用例实际上是一种解决问题的解决方案。"但也许它有助于扩大思维的可能性。

也就是说,在枚举中嵌入函数与任何其他函数参数一样有用。例如,您可以使用它以错误类型传递恢复功能:

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

或者你可以通过"如何转换到下一个状态"在任何状态机(这是枚举的一种常见用途)。

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

这将允许每个状态转换直接控制下一个状态转换,这在某些情况下比使所有逻辑集中更好(特别是如果合法转换是路径依赖的)。

但是,正如@ luk2302所说,功能值只是值。如果枚举可以包含任何值而不是函数,那将是一个非常不幸的特殊情况。

答案 1 :(得分:0)

我认为当你想要例如乘法时,按一定数量添加等等,你可以使用带闭包的枚举。这可能不是最好的例子,当然它不是唯一的解决方案,但我认为可以将闭包与枚举关联起来。

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