如何将 Swift "switch case is ..." 块转换为面向循环的代码?
How to convert Swift "switch case is ..." block into loop oriented code?
我的代码如下所示:
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 个)共同基础 class 的子 class,我需要一个一个地检查它们。这些 subclasses 代表解析器,我正在一个接一个地尝试它们以发现哪个解析器正确解析了一些数据。
如果我在解析时失败,我会调用函数 trynext
到 return 和 "next parser" 来尝试。你可以想象,如果构造函数接受参数(所有 subclass 都接受相同的参数),这个 switch
语句会变得不屈服,并且 subclass 越多,等等
有什么方法可以通过将 classes 放入某种数组并以某种方式循环遍历它来简化此代码?我的想法是减少样板文件,以便我最终使用像 [A, B, C]
这样的结构,这意味着要尝试的子 classes 和尝试它们的顺序。
我会使用一个协议(例如:"Parser")来定义一个 接口 来描述解析器可以做什么。例如:解析(数据);
此协议的不同实现(A、B、C...)将有自己的代码来处理解析。
解析控制器(或管理器或您想到的任何名称)将存储 Parser
个对象的数组。
在forEach循环中,你可以调用每个try Parser.parse(data); ...如果解析正常,则处理进入下一个或中止。
您的解析器(A、B、C…)的特定实现与调用者无关(本应如此)。 ParsingController(你现在有开关)根本不在乎发生了什么。它只对成功或失败感兴趣,分别停止或尝试下一个(如果有下一个)。
更新:我创建了一个小的 Playground 代码,您可以粘贴并了解我的意思。
更新 2:我添加了一个 扩展协议 这样你就可以看到如何实现类似于 抽象 class拥有 base/common 组 functions/values。
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 return 为假)和成功是因为 C return 为真。然后是常用方法的输出。
我的代码如下所示:
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 个)共同基础 class 的子 class,我需要一个一个地检查它们。这些 subclasses 代表解析器,我正在一个接一个地尝试它们以发现哪个解析器正确解析了一些数据。
如果我在解析时失败,我会调用函数 trynext
到 return 和 "next parser" 来尝试。你可以想象,如果构造函数接受参数(所有 subclass 都接受相同的参数),这个 switch
语句会变得不屈服,并且 subclass 越多,等等
有什么方法可以通过将 classes 放入某种数组并以某种方式循环遍历它来简化此代码?我的想法是减少样板文件,以便我最终使用像 [A, B, C]
这样的结构,这意味着要尝试的子 classes 和尝试它们的顺序。
我会使用一个协议(例如:"Parser")来定义一个 接口 来描述解析器可以做什么。例如:解析(数据);
此协议的不同实现(A、B、C...)将有自己的代码来处理解析。
解析控制器(或管理器或您想到的任何名称)将存储 Parser
个对象的数组。
在forEach循环中,你可以调用每个try Parser.parse(data); ...如果解析正常,则处理进入下一个或中止。
您的解析器(A、B、C…)的特定实现与调用者无关(本应如此)。 ParsingController(你现在有开关)根本不在乎发生了什么。它只对成功或失败感兴趣,分别停止或尝试下一个(如果有下一个)。
更新:我创建了一个小的 Playground 代码,您可以粘贴并了解我的意思。
更新 2:我添加了一个 扩展协议 这样你就可以看到如何实现类似于 抽象 class拥有 base/common 组 functions/values。
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 return 为假)和成功是因为 C return 为真。然后是常用方法的输出。