swift - 开启数组类型

标签 swift switch-statement

概览

我想通过匹配数组类型来使用 switch 语句。我有以下类(class)。

类:

class A {}    
class B : A {}

开启单值工作:

let a : A = B()

switch a {
case let b as B:
    print("b = \(b)")
default:
    print("unknown type")
}

开启阵列(编译错误):

let aArray : [A] = [B(), B()]

switch aArray {
case let bArray as [B] :
    print("bArray = \(bArray)")
default:
    print("unknown type")
}

错误:

Downcast pattern value of type '[B]' cannot be used

注意Swift 4

上测试

问题:

  • 我怎样才能做到这一点?

最佳答案

在 Swift 4.1 中,您会收到更好的错误消息(感谢 #11441 ):

Collection downcast in cast pattern is not implemented; use an explicit downcast to '[B]' instead

简而言之,您遇到了一些尚未完全实现的编译器,其进度由错误跟踪 SR-5671 .

但是,您可以通过在执行强制转换之前强制转换为 Any 来解决此限制:

class A {}
class B : A {}

let aArray : [A] = [B(), B()]

switch aArray /* or you could say 'as Any' here depending on the other cases */ {
case let (bArray as [B]) as Any:
  print("bArray = \(bArray)")
default:
  print("unknown type")
}

// bArray = [B, B]

为什么会这样?首先,介绍一下背景。数组、字典和集合由 Swift 的转换机制特殊处理——尽管它们是泛型类型(默认情况下是不变的),Swift 允许您在不同元素类型的集合之间进行转换(有关更多信息,请参阅 this Q&A)。

实现这些转换的函数驻留在标准库中(例如,Arrayimplementation is here )。在编译时,Swift 将尝试识别集合向下转换(例如 [A] 在您的示例中为 [B] )以便它可以直接调用上述转换函数,并避免必须通过 Swift 运行时进行完整动态转换。

但是问题在于,这种专用逻辑并未针对集合向下转换模式(例如在您的示例中)实现,因此编译器会发出错误。通过首先强制转换为 Any,我们强制 Swift 执行完全动态的转换,通过运行时进行调度,最终将调用上述转换函数。

虽然在必要的专用逻辑到位之前,为什么编译器不能暂时将此类转换视为完全动态转换,但我不太确定。

关于swift - 开启数组类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49406684/

相关文章:

ios - 如何编辑 UIScrollView 大小?

ios - iOS 上的低延迟音频输出问题(又名如何击败 AUAudioUnit SampleRate、MaximumFramesToRender 和 ioBufferDuration 提交)

swift - 转义闭包捕获非转义参数派发

ios - Swift:图表填充线等

java - 合并多个 if 语句

c - 如何将开关箱内的箱子软分隔

ios - 如何将项目中定义的字符串用于 Storyboard 中定义的 UILabel?

Java switch 语句

javascript - switch 语句给出了错误的月份如何修复?

javascript - 为什么我的开关不起作用?