首页 > 解决方案 > 为什么在 Swift 中向下转换数组项?

问题描述

如果数组项的子类已知,为什么我必须在 Swift 中向下转换数组项?

 > class B {let t: String = "-B-"}
 > class B1:B {let t1: String = "-B1-"}
 > class B2:B {let t2: String = "-B2-"}
 > let bunch = [B(), B1(), B2()]

正如预期的那样:

 > print(type(of:bunch))
 Array<B>

数组的每个元素的子类是已知的:

 > for item in bunch {print(type(of:item))}
 B
 B1
 B2

然而(如记录)我们无法访问该项目的子类成员,我们必须降级:

> if bunch[1] is B1 {let b1 = bunch[1] as! B1; print(b1.t1)} 
-B1-

因为这不起作用:

> bunch[1].t1
error: repl.swift:17:6: error: value of type 'B' has no member 't1'; did you mean 't'?

为什么 Swift 可以使用 type(of:) 确定子类,但在访问该子类中的成员时却无法推断?这是一个错误,一个历史性的宿醉,还是我错过了什么?

标签: swiftdowncast

解决方案


简单的答案是,一旦您声明了类型数组,B编译器就会将数组中的所有元素都视为类型B,并且不会根据存在的任何子类自动推断方法。您似乎想知道为什么编译器/数组不够聪明,无法确定已let声明数组的类,而理论上它可以。我不确定许多语言是否支持这样的功能,无论如何你都可以通过像你一样简单地打开它来做同样的事情,因为在这种情况下你知道它。


推荐阅读