Swift: перечисления, которые используют закрытие?

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

Я планирую использовать основные данные в качестве хранилища данных и создать простую взаимосвязь между node и правилом.

В objective-c я, вероятно, создавал классы для каждого из правил и имел бы их соответствие протоколу.

NSArray *ruleClassNames = @[@"SimpleRuleA",@"SimpleRuleB",@"BigFatComplicatedRule"];

int ruleType = [someNode.rules firstObject];
Class class = NSClassFromString(ruleClassNames[ruleType]);

[(ruleClassProtocol*)class performSelector:@selector(runRuleOnNode:) withObject:someNode];

Каким будет самый элегантный способ сделать это быстро?

Ответ 1

Решение

Если мы хотим добавить closure в enum, сначала определим тип closure.

typealias Logic = () -> (String)

Затем enum:

enum Rule {
    case SimpleRuleA(Logic)
    case SimpleRuleB(Logic)
    case BigFatComplicatedRule(Logic)
}

Что это! Давайте посмотрим, как это использовать.

Использование

Создайте пару Logic(s):

let logic0 : Logic = { return "Logic 0" }
let logic1 : Logic = { return "Logic 1" }

И теперь функция для обработки Rule

func processRule(rule:Rule) -> String {
    switch rule {
    case .SimpleRuleA(let logic): return "Simple Rule A, logic: \(logic())"
    case .SimpleRuleB(let logic): return "Simple Rule B, logic: \(logic())"
    case .BigFatComplicatedRule(let logic): return "Big Fat Complicated Rule, logic: \(logic())"
    }
}

Наконец, объедините все возможные правила со всеми возможными Logic...

let aWithLogic0 = Rule.SimpleRuleA(logic0)
let aWithLogic1 = Rule.SimpleRuleA(logic1)
let bWithLogic0 = Rule.SimpleRuleB(logic0)
let bWithLogic1 = Rule.SimpleRuleB(logic1)
let fatWithLogic0 = Rule.BigFatComplicatedRule(logic0)
let fatWithLogic1 = Rule.BigFatComplicatedRule(logic1)

... и протестировать его

processRule(aWithLogic0) // "Simple Rule A, logic: Logic 0"
processRule(aWithLogic1) // "Simple Rule A, logic: Logic 1"
processRule(bWithLogic0) // "Simple Rule B, logic: Logic 0"
processRule(bWithLogic1) // "Simple Rule B, logic: Logic 1"
processRule(fatWithLogic0) // "Big Fat Complicated Rule, logic: Logic 0"
processRule(fatWithLogic1) // "Big Fat Complicated Rule, logic: Logic 1"

Является ли это решение близким к тому, что вы имели в виду?

Ответ 2

    enum FunctionEnum
   {
     case binaryOperation((Double,Double)->Double)
     constant(Double)
   }

1.Вы можете связать значения с перечисляемыми случаями, следовательно, он также имеет тип здесь, например, binaryOperation имеет тип       ((Double, Double) → Double), что означает его тип замыкания, которое принимает два удвоения и возвращает один