Подтвердить что ты не робот

Можно ли создать тип Enum в Swift с типом Raw Values ​​Closure?

Как я пробовал следующий код, я получаю некоторые ошибки.

enum Operate: ((Double, Double) -> Double) = {
    case Plus = {$1 + $0}
    case Minus = {$1 - $0}
    case Multiply = {$1 * $0}
    case Divide = {$1 / $0} 
}

Можно ли создать тип Enum в Swift с типом Raw Values ​​Closure? Спасибо.

4b9b3361

Ответ 1

Как сказал @Pang, в качестве исходного типа могут использоваться только строки, символы или любое целое число типов с плавающей запятой. Однако вы можете достичь чего-то подобного, используя struct:

struct Operate {
    typealias OperationType = (Double, Double) -> Double

    static let Plus : OperationType = { $0 + $1 }
    static let Minus: OperationType = { $0 - $1 }
    // ...
}

let plus = Operate.Plus
plus(1.0, 2.0) // 3.0

Ответ 2

Другой возможный способ, но используя enum:

typealias TwoOp = (Double, Double) -> Double

enum Operate {

    case Plus, Minus // etc...

    var op: TwoOp {
        get {
            switch self {
            case .Plus:
                return {$1 + $0}
            case .Minus:
                return {$1 - $0}
            }
        }
    }
}

let opPlus = Operate.Plus
let answerP = opPlus.op(3, 2)
let opMinus = Operate.Minus
let answerM = opMinus.op(3, 2)

Ответ 3

Необработанное значение не может быть закрытием, но есть другой вариант для перечислений.

Enums поддерживают связанное значение, которое может содержать любой тип, который вы хотите. Вы можете использовать связанное значение для хранения вашего закрытия. Взгляните на Swift Language iBook для получения дополнительной информации о связанных с перечислением значениях.

Ответ 4

Как указал @Duncan C вместо создания enum с необработанными типами, вы можете создать enum, где каждый случай имеет связанное значение следующим образом:

    private enum Operation {
            case BinaryOperation((Double, Double) -> Double)
            case UrinaryOperation((Double) -> Double)
        }

Тип связанного значения находится в скобках рядом с каждым случаем. В отличие от исходных значений, связанные значения могут быть закрытыми.

Затем вы можете создать переменную типа Operation с ассоциированным значением типа (Double, Double) -> Double:

let plus = Operation.BinaryOperation({$0 + $1})
let minus = Operation.BinaryOperation({$0 - $1})
let multiply = Operation.BinaryOperation({$0 * $1})
let divide = Operation.BinaryOperation({$0 / $1})
let plus = Operation.BinaryOperation({$0 + $1})

let abs = Operation.UrinaryOperation({abs($0)})

и используйте их:

plus(3.0,2.0) //5.0
abs(-4.0)     //4.0