我有这样的代码:
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 个)公共(public)基类的子类,我需要一个一个地检查它们。这些子类代表解析器,我正在一个接一个地尝试它们以发现哪个解析器正确解析了一些数据。
如果我在解析时失败,我会调用一个函数 trynext
来返回“下一个解析器”来尝试。你可以想象,如果构造函数接受参数(所有子类接受相同的参数),并且有更多的子类等等,这个 switch
语句会变得不屈服。
有什么方法可以通过将类放入某种数组并以某种方式循环遍历它来简化此代码吗?我的想法是减少样板文件,以便我最终使用像 [A, B, C]
这样的结构,它暗示要尝试的子类和尝试它们的顺序。
最佳答案
我会使用一个协议(protocol)(例如:“解析器”)来定义一个描述解析器可以做什么的接口(interface)。例如:解析(数据);
此协议(protocol)的不同实现(A、B、C……)将有自己的代码来处理解析。
解析 Controller (或管理器或您想到的任何名称)将存储一个 Parser
对象数组。
在一个forEach循环中,你可以调用每个try Parser.parse(data); ...如果解析正常,则处理进入下一个或中止。
您的解析器(A、B、C……)的特定实现与调用者无关(本应如此)。 ParsingController(你现在有开关)根本不在乎发生了什么。它只对成功或失败感兴趣,分别停止或尝试下一个(如果有下一个)。
更新:我创建了一个小的 Playground 代码,您可以粘贴并了解我的意思。
更新 2:我添加了一个扩展协议(protocol),因此您可以了解如何使类似于抽象 类的东西拥有一组基本/通用的函数/值。
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 返回假)和成功因为 C 返回真。然后是常用方法的输出。
关于swift - 如何将 Swift "switch case is ..." block 转换为面向循环的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34010885/