【问题标题】:swift how to compare genericsswift如何比较泛型
【发布时间】:2015-07-02 10:49:05
【问题描述】:

我有一个名为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'类型的操作数”

不确定我该如何解决这个问题,两个对象都定义为 AnyObject 并确认了 SomeProtocol 协议,那么这里有什么问题?

【问题讨论】:

  • 要问自己的问题:您希望== 做什么?这种在两个任意SomeProtocol 类型上使用== 的能力从何而来?您是否定义了一个带有两个SomeProtocol== 运算符?你想要reference 相等(=== 而不是==)吗?
  • 是的,我想要一个引用相等来检查这是否是同一个对象,但是 === 也不起作用
  • Comparing two custom objects in swiftthis answer 的可能重复项应该可以解决您的问题。

标签: ios swift generics


【解决方案1】:

为了比较两个泛型,您可以声明泛型,以便能够代替您的泛型类型的类型应符合Comparable 协议。

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

现在我们可以做到:-

if heap[parentIndex] < heap[childIndex] {
//Your code
}

这是如何工作的?

正如我们所知,遵守协议意味着在该协议中实现所有必需的方法。 Comparable 协议将所有的比较方法作为必需的参数,任何实现 Comparable 的类型都可以进行比较。

使用泛型进行愉快的编码。

【讨论】:

    【解决方案2】:

    如果您想要引用相等,那么您需要确保 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
    • 这是 2.0 的功能,如果您使用的是 1.2,您仍然需要像原来的问题一样使用循环。
    • 你能举个例子如何从数组中循环和删除对象吗?在目标 c 我曾经将这些 objectsToRemove 存储在一个数组中,然后调用 removeObjectsInArray:
    • 这是一个单独的问题,接受这个问题(假设它回答了你的问题)并发布一个新问题(尽管可能已经有人问这个问题了)
    【解决方案3】:

    泛型函数还必须符合Equatable 协议

    【讨论】:

    • 在这种情况下并不那么简单 - 数组是协议而不是实际对象,因此需要将两种可能不同的类型等同于遵守相同的协议。
    • 我应该定义一个符合协议的 AnyObject 数组吗?我能做到吗?
    • 不,你不能这样做,因为Equatable 有一个关联类型——它只能用作约束,你不能有一个不同Equatable 类型的数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    相关资源
    最近更新 更多