我想实现这样的函数:
protocol Base {
var value: Int { get set }
}
class ObjectTypeA: Base {
var value: Int = 0
}
class ObjectTypeB: Base {
var value: Int = 1
}
var objects: [Base] = [ObjectTypeA(), ObjectTypeB()]
func updatePropertyForType(type: Base.Type, value: Int) {
objects.filter({ $0 is type }).forEach { // <<< ERROR IS HERE
var object = $0
object.value = value
}
}
updatePropertyForType(ObjectTypeB.self, value: 10)
但是有一个错误:
'type' is not a type
请帮助我修复它。
请参阅此答案:
protocol Base: AnyObject {
var value: Int { get set }
}
class ObjectTypeA: Base {
var value: Int = 0
}
class ObjectTypeB: Base {
var value: Int = 1
}
var objects: [Base] = [ObjectTypeA(), ObjectTypeB()]
func updatePropertyForType(type: Base.Type, value: Int) {
objects.filter({let item = $0; return type === item.dynamicType }).forEach {
$0.value = value
}
}
用:
致电updatePropertyForType(ObjectTypeA.self, value: 3)
由于其他答案已经避免使用,因此您不能使用具有is
的元类型。但是,更好的解决方案是简单地使用仿制药。这将允许Swift推断您传递到该功能的类型,从而使其写入:
protocol Base : class {
var value: Int { get set }
}
class ObjectTypeA: Base {
var value: Int = 0
}
class ObjectTypeB: Base {
var value: Int = 1
}
var objects: [Base] = [ObjectTypeA(), ObjectTypeB()]
func updateElements<T:Base>(ofType type: T.Type, withValue value: Int) {
objects.filter{ $0 is T }.forEach{ $0.value = value }
}
updateElements(ofType: ObjectTypeB.self, withValue: 10)
您还需要使您的Base
协议类BOND(: class
)以允许Swift将Base
键入的实例视为参考类型(允许您进行$0.value = value
)。
您以前的代码:
var object = $0
object.value = value
本来可以用于参考类型,但是不是的值类型 - 因为object
这只是$0
的副本,因此任何突变都不会在数组中反映出来。因此,您应该注释您的协议,以明确您的协议不是设计用于价值类型的。
如果您确实想处理价值类型,则可能需要考虑使用map
:
func updateElements<T:Base>(ofType type: T.Type, withValue value: Int) {
objects = objects.map {
var object = $0
if object is T {
object.value = value
}
return object
}
}
,但此代码工作正常。
protocol Base {
var value: Int { get set }
}
class ObjectTypeA: Base {
var value: Int = 0
}
class ObjectTypeB: Base {
var value: Int = 1
}
var objects: [Base] = [ObjectTypeA(), ObjectTypeB()]
func updatePropertyForType(type: Base.Type, value: Int) {
objects.filter({ object in
let result = object.dynamicType == type
return result
}).forEach {
var object = $0
object.value = value
}
}
updatePropertyForType(ObjectTypeB.self, value: 10)
print(objects)