First of all, doing add
is super easy, just include this function to make it work:
func +=(inout lhs: [SomeProtocol], rhs: SomeProtocol) {
lhs.append(rhs)
}
Doing remove
is a lot trickier because SomeProtocol
could apply equally to a class
or struct
, and only values with class types can be compared with ===
.
We could use the ==
operator instead, but it only takes values that conform to the Equatable
protocol, and Equatable
can only be used as a generic constraint (so far), otherwise you could use something like protocol<SomeProtocol,Equatable>
as your array element type.
If you know for sure that your SomeProtocol
will only be applied to classes, consider refactoring your code to work with that class type instead:
protocol SomeProtocol {}
class SomeClass : SomeProtocol {}
var list:[SomeClass] = []
func add(some:SomeClass) {
list += some
}
func remove(some:SomeClass) {
list -= some
}
func +=(inout lhs: [SomeClass], rhs: SomeClass) {
lhs.append(rhs)
}
func -=(inout lhs: [SomeClass], rhs: SomeClass) {
for (i,v) in enumerate(lhs) {
if v === rhs {
lhs.removeAtIndex(i)
break
}
}
}
If you also happen to make SomeClass
conform to Equatable
the usual array functions will work automatically, and you won't even need to overload +=
and -=
.
Otherwise, if you can't know whether your value will be a class or a struct, it might be better to think about what it means for values of SomeProtocol
to be "equal" and require a comparison method:
protocol SomeProtocol {
func isEqualTo(some: SomeProtocol) -> Bool
}
func -=(inout lhs: [SomeProtocol], rhs: SomeProtocol) {
for (i,v) in enumerate(lhs) {
if v.isEqualTo(rhs) {
lhs.removeAtIndex(i)
break
}
}
}
// add functions work the same as above
Alternatively, you could use your original code and write a global comparison function:
func ===(lhs: SomeProtocol, rhs: SomeProtocol) -> Bool {
// return something based on the properties of SomeProtocol
}