如何将Swift“switch case is ...”块转换为面向循环的代码?

时间:2015-12-01 01:04:15

标签: swift class switch-statement

我的代码看起来像这样:

class Base {
    func launch(code1: Int, code2: Int) -> Bool { return false }
}

class A: Base {}
class B: Base {}
class C: Base {}

func trynext(obj: Base) -> Base? {
    switch obj {
    case is A: return B()
    case is B: return C()
    default: return nil
    }
}

基本上,我有很多(比如20个)公共基类的子类,我需要逐个查看它们。这些子类代表解析器,我一个接一个地尝试它们,以发现哪个解析器正确地解析了一些数据。

如果我在解析时失败,我会调用函数trynext来返回“下一个解析器”来尝试。你可以想象,如果构造函数接受参数(所有子类采用相同的参数),并且存在的子类越多,这个switch语句就会变得非常简单。

有没有什么方法可以通过将类放入某种数组并以某种方式循环遍历来简化此代码?我的想法是减少样板,以便最终使用类似[A, B, C]的结构,这意味着要尝试的子类和尝试它们的顺序。

1 个答案:

答案 0 :(得分:1)

我会使用一个协议(比如说:" Parser")来定义描述解析器可以做什么的接口。例如:解析(数据);

本协议的不同实现(A,B,C ......)将有自己的代码来处理解析。

解析控制器(或管理器或您提出的任何名称)将存储Parser个对象的数组。

在forEach循环中,你可以调用每次尝试Parser.parse(data); ...如果解析正常,则处理下一个或中止。

您的解析器(A,B,C ......)的特定实现与调用者无关(应该如此)。 ParsingController(你现在有你的开关),不会关心会发生什么。它只对成功或未能分别停止或尝试下一个(如果有下一个)感兴趣。

更新:我创建了一个小的Playground代码,你可以粘贴,看看我的意思。

UPDATE2:我添加了一个扩展协议,这样你就可以看到如何使用类似于 abstract 类的东西来拥有一组基本/公共的函数/值集。

import Swift

protocol Parser {
    func parse(code1: Int, code2: Int) -> Bool
}

extension Parser {
    var someCalculatedProperty: Int {
        return 12345
    }
    func someCommonMethod() {
        print("Some Common Method")
    }
}

class A : Parser {
    func parse(code1: Int, code2: Int) -> Bool { return false }
}
class B : Parser {
    func parse(code1: Int, code2: Int) -> Bool { return false }
}
class C : Parser {
    func parse(code1: Int, code2: Int) -> Bool { return true }
}

// Create 4 Parsers (two of the same type, just to demonstrate)
var parsers = [Parser](arrayLiteral: A(), A(), B(), C())

// Iterate the parsers until we get a success
for parser in parsers {
    if parser.parse(0, code2: 1) {
        print("Success")
        // Just for fun, call common parser methods.
        parser.someCommonMethod()
        print(parser.someCalculatedProperty)
        break
    } else {
        print("Fail")
    }
}

输出应为:

Fail
Fail
Fail
Success
Some Common Method
12345

3失败(因为A,A,B返回false)和成功因为C返回true。然后是常用的方法'输出