Swift如何比较泛型?

4

我有一个叫做SomeProtocol的协议。

我希望创建一个函数,该函数获取符合此协议的对象,并将其添加到数组中。

然后,我又有另一个函数,用于从该数组中删除一个对象。

var allObjs = [SomeProtocol]()

func addObj<T: AnyObject where T: SomeProtocol>(obj: T) {
    allObjs.append(obj)
}

func removeObj<T: AnyObject where T: SomeProtocol>(obj: T) {
    for someObj in allObjs {
        if someObj == obj { // compile time error -> Binary operator '==' cannot be applied to operands of type 'SomeProtocol' and 'T'

        }
    }
}  

这段代码会导致编译时错误:"二进制运算符 '==' 不能应用于类型为 'SomeProtocol' 和 'T' 的操作数"

我不确定如何解决这个问题,因为两个对象都被定义为遵循 SomeProtocol 协议的 AnyObject 类型,那么问题在哪里呢?


需要问自己的问题:你期望 == 做什么?这种在两个任意的 SomeProtocol 类型上使用 == 的能力从哪里来?你是否定义了一个接受两个 SomeProtocol== 运算符?你想要引用相等性 (=== 而不是 ==) 吗? - Airspeed Velocity
是的,我想要一个引用相等性来检查是否为同一对象,但是 === 也不起作用。 - Mario
可能是在Swift中比较两个自定义对象的重复问题,而且这个答案应该可以解决你的问题。 - Martin R
3个回答

4

要比较两个泛型,你可以声明这些泛型,使得能够在你的泛型类型位置上的类型符合Comparable协议。

struct Heap<T: Comparable>{
var heap = [T]()
}}

现在我们将能够做到:-
if heap[parentIndex] < heap[childIndex] {
//Your code
}

这是如何工作的?

我们知道,符合协议意味着实现该协议中所有所需的方法。 可比较 协议已经包含了所有比较方法作为必需参数,任何实现 可比较 的类型都将能够进行比较。

使用泛型开心编码。


1
如果您想要引用相等性,则需要确保SomeProtocol只适用于类(因为您无法在结构体上使用引用相等性,因为它们是值类型):
protocol SomeProtocol: class { }

现在只有类可以实现SomeProtocol

您现在无需使用泛型即可使用引用相等性,只需要普通的运行时多态性:

func removeObj(obj: SomeProtocol) {
    // since any SomeProtocol-conforming object
    // must be a class, you can now use ===
    if let idx = allObjs.indexOf({ $0 === obj}) {
        allObjs.removeAtIndex(idx)
    }
}

由于某些原因,我无法在我的数组上调用indexOf方法。 - Mario
那是一个2.0版本的功能,如果你正在使用1.2版本,你仍然需要像在你原来的问题中一样用循环来完成它。 - Airspeed Velocity
请问您能否举个例子,如何循环并从数组中删除对象?在 Objective-C 中,我习惯将这些要删除的对象存储在一个数组中,然后调用 removeObjectsInArray: 方法。 - Mario
那是一个单独的问题,请接受这个答案(假设回答了你的问题),然后发布一个新的问题(虽然可能已经有人问过了)。 - Airspeed Velocity

0

通用函数还必须符合Equatable协议。


在这种情况下并不像那么简单 - 数组是协议而不是实际对象,因此需要将两个可能不同类型但都遵循相同协议的对象进行等价比较。 - Airspeed Velocity
我应该定义一个遵循协议的 AnyObject 数组吗?我真的能这样做吗? - Mario
不行,因为Equatable有一个关联类型 - 它只能用作约束条件,你不能拥有不同Equatable类型的数组。 - Airspeed Velocity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接