【问题标题】:Cast Protocol to Class in Swift在 Swift 中将协议转换为类
【发布时间】:2019-10-02 09:52:34
【问题描述】:

当我们像这样进行可选链接时

var myVar: Int?

if let unwrapped = myVar {

}

编译器将unwrapped 视为Int

我有一系列符合特定协议的类。考虑示例:

import Foundation

protocol SomeProtocol: class {}

class A {}
extension A: SomeProtocol {}
class B {}
extension B: SomeProtocol {}
class C {}
extension C: SomeProtocol {}

let arr: [SomeProtocol] = [A(), B(), C()]

arr.forEach{ object in
  if object is A {
    // object is treated like SomeProtocol, not like A class
  }
}

我可以做到(object as! A),但这看起来很难看。如何找到将协议项智能转换为我的班级变量的方法?

【问题讨论】:

  • 我想这是唯一有效的方法

标签: swift


【解决方案1】:

使用可选绑定,您走在正确的道路上。

as?as! 的变体,其计算结果为您要转换的类型的可选项。您可以将其与可选绑定一起使用:

arr.forEach{ object in
  if let a = object as? A { // (object as? A) is of type "A?", but we are unwrapping it
    // a is of type A now
  }
}

【讨论】:

  • 谢谢!我以为是?仅在您处理可选项时使用。
  • @EvgeniyKleban 也可以在你想投的时候使用。如果强制转换失败,它的计算结果为 nil。
【解决方案2】:

您可以使用case let 稍微清理一下。以您上面的示例为例,可以将其更改为

protocol SomeProtocol: class {}

class A {}
extension A: SomeProtocol {}
class B {}
extension B: SomeProtocol {}
class C {}
extension C: SomeProtocol {}

let arr: [SomeProtocol] = [A(), B(), C()]

for case let object as A in arr {
    print("item is A")
}

这将循环遍历数组,如果项目可以转换为指定的类型,则 for 循环的主体将执行。它只是去掉了一行嵌套,看起来更干净一些,虽然最终和上面 Sweeper 的回答一样

【讨论】:

    【解决方案3】:

    switch 语句中使用模式匹配

    如果您要在同一个循环中处理多个类型,使用带有 模式匹配switch 来确定类型很方便:

    示例:

    protocol SomeProtocol: class {}
    
    class A {
        let foo = 17
    }
    extension A: SomeProtocol {}
    class B {
        let bar = "hello"
    }
    extension B: SomeProtocol {}
    class C {
        let baz = true
    }
    extension C: SomeProtocol {}
    class D: SomeProtocol {}
    
    let arr: [SomeProtocol] = [D(), A(), C(), B()]
    
    for object in arr {
        switch object {
        case let a as A:
            print("object is A")
            print(a.foo)
        case let b as B:
            print("object is B")
            print(b.bar)
        case let c as C:
            print("object is C")
            print(c.baz)
        default:
            print("object is some other type")
        }
    }
    

    输出:

    object is some other type
    object is A
    17
    object is C
    true
    object is B
    hello
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-05
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多