将可选类型转换为非可选类型
Convert an optional Type to non-optional Type
以下代码会引发编译错误:
import UIKit
class Initable {
required init() {}
}
class NestedObject:Initable {
var nestedProp:String? = nil
}
class MyObj {
var name:String? = nil
var value:Int? = nil
var otherVals:[String]? = nil
var nestedObj:NestedObject? = nil
}
let obj = MyObj()
var nestedObj = obj[keyPath: \MyObj.nestedObj]
if(nestedObj == nil) {
nestedObj = type(of: obj[keyPath: \MyObj.nestedObj]).init()
}
nestedObj![keyPath: \NestedObject.nestedProp] = "NEST ME BABY!!"
obj[keyPath: \MyObj.nestedObj] = nestedObj!
obj
这是因为type(of: obj[keyPath: \MyObj.nestedObj])
是NestedObject?
,当然不能初始化。我需要一种方法来解开可选类型并获得非可选类型 NestedObject
.
必须维持的假设。
- 我必须使用可选值,因为
nestedObj
有可能为零。
- 我不知道
NestedObject
是什么类型。它可以是任何类型,但我确信这些类型都是 Initable
.
- 我需要能够通过键路径设置我的
nestedObject
的 属性。
- 如果
nestedObject
为 nil,我需要创建一个新的 NestedObject
并通过键路径设置值。
这是较大系统的一小部分,因此必须考虑上述假设。我不能改变这些。
您可以使用可选的 Wrapped
类型来初始化嵌套对象:
let obj = MyObj()
let nestedObj = type(of: obj[keyPath: \MyObj.nestedObj]).Wrapped()
nestedObj[keyPath: \NestedObject.nestedProp] = "NEST ME BABY!!"
print(nestedObj.nestedProp ?? "") // "NEST ME BABY!!"
如果您希望生成的对象也是可选的:
let obj = MyObj()
var nestedObj = obj[keyPath: \MyObj.nestedObj]
if nestedObj == nil {
nestedObj = type(of: obj[keyPath: \MyObj.nestedObj]).Wrapped()
}
nestedObj?[keyPath: \NestedObject.nestedProp] = "NEST ME BABY!!"
您需要添加这些助手:
protocol AnyOptional {
associatedtype Wrapped
var optional: Optional<Wrapped> { get }
}
extension Optional: AnyOptional {
var optional: Optional<Wrapped> { self }
}
以下代码会引发编译错误:
import UIKit
class Initable {
required init() {}
}
class NestedObject:Initable {
var nestedProp:String? = nil
}
class MyObj {
var name:String? = nil
var value:Int? = nil
var otherVals:[String]? = nil
var nestedObj:NestedObject? = nil
}
let obj = MyObj()
var nestedObj = obj[keyPath: \MyObj.nestedObj]
if(nestedObj == nil) {
nestedObj = type(of: obj[keyPath: \MyObj.nestedObj]).init()
}
nestedObj![keyPath: \NestedObject.nestedProp] = "NEST ME BABY!!"
obj[keyPath: \MyObj.nestedObj] = nestedObj!
obj
这是因为type(of: obj[keyPath: \MyObj.nestedObj])
是NestedObject?
,当然不能初始化。我需要一种方法来解开可选类型并获得非可选类型 NestedObject
.
必须维持的假设。
- 我必须使用可选值,因为
nestedObj
有可能为零。 - 我不知道
NestedObject
是什么类型。它可以是任何类型,但我确信这些类型都是Initable
. - 我需要能够通过键路径设置我的
nestedObject
的 属性。 - 如果
nestedObject
为 nil,我需要创建一个新的NestedObject
并通过键路径设置值。
这是较大系统的一小部分,因此必须考虑上述假设。我不能改变这些。
您可以使用可选的 Wrapped
类型来初始化嵌套对象:
let obj = MyObj()
let nestedObj = type(of: obj[keyPath: \MyObj.nestedObj]).Wrapped()
nestedObj[keyPath: \NestedObject.nestedProp] = "NEST ME BABY!!"
print(nestedObj.nestedProp ?? "") // "NEST ME BABY!!"
如果您希望生成的对象也是可选的:
let obj = MyObj()
var nestedObj = obj[keyPath: \MyObj.nestedObj]
if nestedObj == nil {
nestedObj = type(of: obj[keyPath: \MyObj.nestedObj]).Wrapped()
}
nestedObj?[keyPath: \NestedObject.nestedProp] = "NEST ME BABY!!"
您需要添加这些助手:
protocol AnyOptional {
associatedtype Wrapped
var optional: Optional<Wrapped> { get }
}
extension Optional: AnyOptional {
var optional: Optional<Wrapped> { self }
}