ios - 无法执行存储在 Array[Any] 中的对象的方法
问题描述
我想将不同类型的对象存储在一个数组中。下面的程序只是一个最小的演示。在 anyArray:[Any] 中存储了 Object1 的一个实例。print 语句打印出预期的对象类型。在下一行中,存储对象类型的测试返回 true。这意味着,在运行期间,正确的对象类型是已知的,并且一切似乎都很好。
class Object1 {
var name = "Object1"
}
var anyArray:[Any] = [Object1()]
print("\(type(of: anyArray[0]))")
let testResult = anyArray[0] is Object1
print("Test result:\(testResult)")
//print("Name:\((anyArray[0]).name)")
Console output:
Object1
Test result:true
但是,如果我尝试打印出对象的 name 属性,我会从编辑器中收到一条错误消息:
Value of type 'Any' has no member 'name'
好吧,在编译时对象的类型是未知的。这就是编译器抱怨的原因。如何告诉编译器可以访问存储对象的属性?
解决方案
区别来自于类型检查的区别:
- 运行时,或
- 编译时间
运算符在is
运行时检查表达式是否可以转换为指定的类型。type(of:)
在运行时检查确切的类型,而不考虑子类。
anyArray[0].name
由于 TypeAny
没有name
属性,因此无法编译。
如果您确定anyArray[0]
是 a Object1
,则可以使用 downcast 运算符as!
:
print("\((anyArray[0] as! Object1).name)")
要在运行时检查来自的元素anyArray
是否可以是Object1
使用可选绑定,请使用条件转换运算符as?
:
如果让:
if let object = anyArray[0] as? Object1 { print(object.name) }
guard
如果您想在范围的其余部分使用该对象,或者使用该语句:guard let object = anyArray[0] as? Object1 else { fatalError("The first element is not an Object1") } print(object.name)
如果您的数组中的所有对象都有一个name
属性,并且您不想反复经历可选绑定的所有环节,那么请使用协议。您的代码将如下所示:
protocol Named {
var name: String {get set}
}
class Object1: Named {
var name = "Object1"
}
var anyArray:[Named] = [Object1()]
print("\(type(of: anyArray[0]))")
let testResult = anyArray[0] is Object1
print("Test result:\(testResult)")
print("Name:\(anyArray[0].name)")
请注意,anyArray
它现在是一个对象数组Named
,并且Object1
符合Named
协议。
要了解有关协议的更多信息,请查看此处。
推荐阅读
- css - 角形材质迷你按钮周围显示一些正方形
- javascript - 如何将 JSON 对象获取到 React 组件?
- python - 如何将json转换为数据框
- javascript - 在使用 For 循环 JS 中分配变量
- python - 没有传入时如何避免“1”
- c# - ac#软件使用adb控制安卓设备
- php - mysql和PHP中两个日期的区别
- python - 在 Ubuntu 18.04 中导入 tensorflow-gpu 时遇到问题
- json - 在 json 模式中使用“$ref”时出现 MalformedURLException
- git-config - 无法更新 git config:无法锁定文件 [home]/snap/gitkraken/137/.gitconfig.lock' 以进行写入: