在objectiveC库中有许多基于其类的名称(字符串表示)实例化对象的情况。
我与以下工作代码非常接近:
class Person{
var age:Int = 1
//somehow this is critical
required init () {
}
}
class Dog{
var color:String = "Blue"
//somehow this is critical
required init () {
}
}
/*
The basics
*/
let X = Person.self
var p1 = X()
p1.age = 5
println(p1.age)
/*
Instantiate from a String
*/
var hash1 = ["person":Person.self]
if let t = hash1["person"]{
let p2 = t()
p2.age = 8
println(p2.age)
}
字典的最后一个片段接近真实世界的实现应该是什么样子,除了我们需要能够将多个Type放入字典中;辨别两者并从结果中实例化。类似于以下非工作代码:
var hash2 = ["dog":Dog.self, "person":Person.self] // needed for real-world usage
if let t2 = hash2["person"]{ // warning
let p3 = t2() //error
p3.age = 11
println(p3.age)
}
答案 0 :(得分:5)
请参阅,Swift是一种非常类型安全的语言。所以当你弄乱任何不同的类型时,最好对编译器说什么我们会搞乱。
所以hash2
行看起来像这样:
var hash2: [String: Any] = ["dog": Dog.self, "person": Person.self]'
这里你要说的是,该字典将使用字符串的键类型和任意类型的值(AnyObject来自Obj-c中的NSObject,这里是任何类型,因为Dog.self和Person.self不是来自obj -c和不一样的类型)
然后,在展开时,您需要说出它将是什么类型,所以下一个代码将是这样的:
if let t2 = hash2["person"] as? Person.Type {
let p3 = t2()
p3.age = 11
println(p3.age)
}
在这里,我不仅尝试从字典中获取密钥,而且还尝试将其转换为Person.Type
类型。当我提到字典正在减速时,贝塞尔值可以是Any
类型,我需要将其转换为特定类型才能使用age
属性和()
操作
UPD:
Swift是类型安全的,因此如果myObj.age
不是来自myObj
并且没有特定类型,则您无法NSObject
。在你的例子中,Dog和Person没有任何相似之处,因此将它们组合在一起是不合逻辑的。
如果它有相似之处,那么你可以创建协议并投射到它。示例如下:
protocol Aged {
var age: Int {get set}
init()
}
class Person: Aged {
var age: Int = 1
//somehow this is critical
required init () {
}
}
class Dog: Aged {
var age: Int = 5
var color:String = "Blue"
//somehow this is critical
required init () {
}
}
var hash2: [String: Any] = ["dog":Dog.self, "person":Person.self] // needed for real-world usage
if let t2 = hash2["person"] as? Aged.Type {
let p3 = t2()
println(p3.age)
}