在充满自定义对象的模型中获取第一个不为 nil 的值
Get first value that is not nil in a model full of custom objects
所以我有这个模型:
public class Loot {
let sword: Sword?
let armor: Armor?
init(sword: Sword? = nil, armor: Armor? = Armor()) {
self.sword = sword
self.armor = armor
}
}
所有这些属性都继承自 Item
class。
在这个模型中,我将始终只有 1 个属性不为零。有什么办法可以取到这个吗?
使用这个:
extension Sequence where Element == Loot {
var items: [Item] {
var internaltems: [Item] = []
for loot in self {
let mirror = Mirror(reflecting: loot)
let item = mirror.children.first { (label, value) -> Bool in
let internalValue = value as? Item
return internalValue != nil
}
if let item = item {
internaltems.append(item.value as! Item)
}
}
return internaltems
}
}
我可以得到第一个不是 nil 的对象和它的 Item
基数。在提示中用 po loots.items
打印出来我实际上可以看到它是一个 Armor
对象。但它仍然是一个 Item
对象,所以我无法访问 Armor 属性。
您可以拥有一个通用 class 只有一个强制性 属性,而不是持有两个属性,其中只有一个已设置。这样您就不必检查已设置或未设置的内容
class Loot<T: Item> {
let item: T
init(item: T) {
self.item = item
}
}
示例
let loot1 = Loot(item: Armor())
let loot2 = Loot(item: Sword())
如果您想以 Armor
或 Sword
的形式访问项目,我建议在扩展中添加计算属性。最好将它们添加到扩展中,因为这不是 class 的核心功能的一部分,如果您创建另一种类型的 Item
,如 Shield
,这也是一个更好的设计,然后您可以在扩展中为其添加一个计算 属性,而无需修改主 class.
extension Loot {
var armor: Armor? {
get {
guard let armor = item as? Armor else {return nil}
return armor
}
}
var sword: Sword? {
get {
guard let sword = item as? Sword else {return nil}
return sword
}
}
}
然后您可以将它们作为可选对象访问
if let armor = loot1.armor {
//do armor stuff
}
所以我有这个模型:
public class Loot {
let sword: Sword?
let armor: Armor?
init(sword: Sword? = nil, armor: Armor? = Armor()) {
self.sword = sword
self.armor = armor
}
}
所有这些属性都继承自 Item
class。
在这个模型中,我将始终只有 1 个属性不为零。有什么办法可以取到这个吗?
使用这个:
extension Sequence where Element == Loot {
var items: [Item] {
var internaltems: [Item] = []
for loot in self {
let mirror = Mirror(reflecting: loot)
let item = mirror.children.first { (label, value) -> Bool in
let internalValue = value as? Item
return internalValue != nil
}
if let item = item {
internaltems.append(item.value as! Item)
}
}
return internaltems
}
}
我可以得到第一个不是 nil 的对象和它的 Item
基数。在提示中用 po loots.items
打印出来我实际上可以看到它是一个 Armor
对象。但它仍然是一个 Item
对象,所以我无法访问 Armor 属性。
您可以拥有一个通用 class 只有一个强制性 属性,而不是持有两个属性,其中只有一个已设置。这样您就不必检查已设置或未设置的内容
class Loot<T: Item> {
let item: T
init(item: T) {
self.item = item
}
}
示例
let loot1 = Loot(item: Armor())
let loot2 = Loot(item: Sword())
如果您想以 Armor
或 Sword
的形式访问项目,我建议在扩展中添加计算属性。最好将它们添加到扩展中,因为这不是 class 的核心功能的一部分,如果您创建另一种类型的 Item
,如 Shield
,这也是一个更好的设计,然后您可以在扩展中为其添加一个计算 属性,而无需修改主 class.
extension Loot {
var armor: Armor? {
get {
guard let armor = item as? Armor else {return nil}
return armor
}
}
var sword: Sword? {
get {
guard let sword = item as? Sword else {return nil}
return sword
}
}
}
然后您可以将它们作为可选对象访问
if let armor = loot1.armor {
//do armor stuff
}