【问题标题】:Using find() on an array of protocol types在协议类型数组上使用 find()
【发布时间】:2014-07-01 14:20:04
【问题描述】:

每当我创建一个协议类型数组时,如何获取该数组中对象的索引?我尝试了以下方法:

protocol aProtocol {
    func doSomething()
}

class aClass: aProtocol, Equatable {
    var aProperty = "test"

    func doSomething() {

    }
}

func == (lhs: aClass, rhs: aClass) -> Bool {
    return lhs.aProperty == rhs.aProperty
}

var testArray = aProtocol[]()
let testObject = aClass()

testArray += testObject

find(testArray, testObject)

在这种情况下,我得到一个“无法转换表达式的类型 '$T4?'键入“aClass””错误。

查看 find() 的方法签名,我们发现该元素应该实现 Equatable(这就是我在上面重载 == 运算符的原因):

func find<C : Collection where C.GeneratorType.Element : Equatable>(domain: C, value: C.GeneratorType.Element) -> C.IndexType?

有没有人知道我做错了什么,或者这种情况是否可能发生?谢谢。

【问题讨论】:

    标签: arrays swift


    【解决方案1】:

    如果 find() 期望它的第一个参数包含 Equatable 的元素,并且它的第二个参数也是 Equatable,那么在非 Equatable aProtocol 元素的数组上调用 find() 将无法编译.

    要修复,请更改为

    protocol aProtocol : Equatable { ... }
    

    然后为您的aClass 定义实现Equatable 协议。

    【讨论】:

    • 这实际上不适用于声明为asProtocol[] 的数组,因为相等运算符必须是func == (lhs: asProtocol, rhs: asProtocol) -&gt; Bool。真正的问题是,如果你有两个类,例如classAclassB,都符合 aProtocolEquatable,您仍然无法将 classA 的实例与 classB 的实例进行比较。因此,您必须基于协议实现平等,而不是为实现它的每个类实现特定平等。
    【解决方案2】:

    [我目前不在 Mac 前,因此无法验证此建议。]

    您重载了 == 函数,但没有将 aClass 标记为符合 Equatable 协议。

    https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/SwiftStandardLibraryReference/Equatable.html

    【讨论】:

    • 感谢您的回复,nisroc。我确实将 aClass 标记为符合 Equatable 协议,所以在我的操场上进行了一些更改后,我一定忘记将它添加到帖子中。我确实仔细检查了即使使用协议仍然会出现错误。立即编辑帖子。
    猜你喜欢
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多