如何转换Swift“switch case is ...”块转换为循环定向代码? [英] How to convert Swift "switch case is ..." block into loop oriented code?

查看:127
本文介绍了如何转换Swift“switch case is ...”块转换为循环定向代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码:

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
    }
}

基本上,我有一个共同的基类需要逐一通过他们。这些子类代表解析器,我一个接一个尝试它们来发现哪个解析器正确解析一些数据。

Basically, I've got a lot (like 20) of subclasses of a common base class and I need to go through them one by one. These subclasses represent parsers and I'm trying them one after another to discover which parser correctly parses some data.

如果我失败了解析,我调用一个函数 trynext 返回下一个解析器尝试。你可以想象这个 switch 语句可以得到unyieldly如果构造函数接受参数(所有子类采用相同的参数),并且有更多的子类,等。

If I fail on a parse, I call a function trynext to return the "next parser" to try. You can imagine that this switch statement can get unyieldly if the constructors take arguments (all subclasses take the same arguments), and the more subclasses there are, etc.

有没有什么办法,我可以通过把类放入某种数组和循环通过它不知何故简化这段代码?这个想法是减少样板,所以我最终使用一个结构,如 [A,B,C] 这意味着子类尝试和尝试它们的顺序。

Is there any way I can streamline this code by putting the classes into some sort of array and loop through it somehow? The idea is to reduce the boilerplate so that I end up using a structure like [A, B, C] that implies the subclasses to try and the order to try them in.

推荐答案

我会使用协议(例如:Parser)定义接口解析器可以做什么。例如:parse(data);

I would use a Protocol (say: "Parser") to define an interface that describes what the parser can do. E.g.: parse(data);

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

Different Implementations of this Protocol (A, B, C…) will have their own code to deal with the parsing.

解析控制器(或者管理器或者你想出的任何名字)将存储一个 Parser 对象的数组。

The Parsing Controller (or Manager or whatever name you come up with), will store an Array of Parser objects.

在forEach循环中,您可以调用每个try Parser.parse(data);

In a forEach loop, you can call each try Parser.parse(data); … and deal with either going to the next or aborting if the parsing was ok.

您的解析器(A,B,C ...)的特定实现与下面的语句无关:调用者(因为它应该是)。 ParsingController(你现在有你的交换机),不用在乎发生了什么。它只对成功或失败感兴趣,分别停止或尝试下一个(如果有下一个)。

The particular implementations of your Parsers (A, B, C…) are irrelevant to the caller (as it should be). The ParsingController (where you have your switch right now), couldn't care less about what happens. It's only interested in success or failure to stop or try the next one respectively (if there's a next).

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

UPDATE: I have created a small Playground code you can paste and see what I mean.

UPDATE2:我添加了一个扩展协议 ,您可以看到类似于抽象类的东西,以具有基本/通用的函数/值集。

UPDATE2: I have added an extension protocol so you can see how to so something akin to an abstract class to have a base/common set of 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返回false)和Success因为C返回true。然后是常用方法的输出。

3 Failures (because A, A, B return false) and the the Success because of C that returns true. Then the common methods' output.

这篇关于如何转换Swift“switch case is ...”块转换为循环定向代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆