【问题标题】:How to switch on class type in Swift?如何在 Swift 中打开类类型?
【发布时间】:2015-11-28 02:07:18
【问题描述】:

我有以下代码:

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

func next(obj: Base) -> Base {
    if obj is A { return B() }
    else if obj is B { return C() }
    else if obj is C { return A() }
    else { return A() }
}

如何将链接的 ifs 表达为单个 switch 语句?

【问题讨论】:

    标签: swift switch-statement


    【解决方案1】:
    extension Base {
    
        func next() -> Base {
            switch self {
            case is A: return B()
            case is B: return C()
            case is C: return A()
            default: return A()
            }
        }
    
    }
    

    【讨论】:

    • 附带说明,如果您有 class X: B 并在其实例上调用 next,它将返回 C,而不是 default 案例中的 A .
    【解决方案2】:

    令人惊讶的是,这正是您所想但没想到会起作用的:

    switch obj {
    case (is A):
        // do something
    case (is B):
        // do something
    case (is C):
        // do something
    default:
        // do something
    }
    

    请注意,括号不是必需的,我只是为了可读性而喜欢它们。

    【讨论】:

      【解决方案3】:

      理想情况下,您可以通过使用多态性来避免在这种情况下使用 if 语句。

      例如,在基类中定义一个方法 X() 并在每个子类中覆盖它以返回 B()、C()、A() 等。

      然后在你的下一个方法中,只需返回 obj.X()。

      here 这个主题还有很多其他内容。强制上诉(Martin Fowler)here

      【讨论】:

      • 不,这样不行。我想将每个对象与其对其他对象的了解分开
      • 如果他可以更改原始类定义,这将有效。如果他不能改变它们,这是行不通的。你不能用扩展来做到这一点,因为从 Swift 2.1 开始,编译器会说“错误:扩展中的声明还不能覆盖”。
      • 我看到你和其他人已经回答了这个问题,这是完全合理的,但是当我看到在生产代码中使用这种条件方法时,它通常不是正确的,可以重构为我描述。
      猜你喜欢
      • 1970-01-01
      • 2014-07-23
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 2017-10-21
      • 1970-01-01
      相关资源
      最近更新 更多