首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift @objc协议不能用作符合“Equatable”协议的类型,因为“Equatable”具有静态要求。

Swift @objc协议不能用作符合“Equatable”协议的类型,因为“Equatable”具有静态要求。
EN

Stack Overflow用户
提问于 2020-02-23 08:02:26
回答 1查看 2K关注 0票数 1

我目前正在用Swift编写一个可重用的UI组件,这个组件应该是从Obj/ Swift世界中使用的(这是一个混合项目)。我定义了一个没有任何关联类型的@objc协议(因为@objc协议不允许这些类型)。在组件中的一种方法中,我需要将协议存储为一种类型,并需要查找特定条目的索引,类似于以下内容-

代码语言:javascript
复制
func select<T: Itemable>(_ item: T) {
    guard let itemIndex = items.index(of: item) else {
        return
    }
  //more stuf
}

其中itemsItemable (协议)类型的数组。

然而,我得到的错误说,我不能使用它作为一种类型符合等价物,因为等式有静态的要求。Itemable的定义如下-

@objc protocol Itemable { //methods and properties }

而且,也不知道如何使它符合平等。很明显,以下几点是有帮助的,但不知道为什么-

代码语言:javascript
复制
func ==<T: <Itemable>>(lhs: T, rhs: T) -> Bool {
    return lhs.aProperty == rhs.aProperty
}

在我看来,这可能需要擦除字体,但我不知道该怎么做。

下面是协议的简略版本,显示了所有不同类型的方法和属性--它实际上没有任何静态或关联的类型。

代码语言:javascript
复制
 @objc protocol Itemable {
    typealias voidBlock = () -> Void
    var color: UIColor { get }
    var screenParameters: [String : String] { get }
    var screenView: String { get }
    var iconImage: UIImage? { get }
    @objc var accessibilityLabel: String? { get }
}

extension Array where Element: Itemable {
    func index(of element: Element) -> Int? {
        index(where: { $0.screenView == element.screenView })
    }
} 
EN

回答 1

Stack Overflow用户

发布于 2020-02-23 16:54:48

您不能使@objc类型符合相等。赤道有自己的要求。目标-C协议不能表达自己的需求。

您的==函数是可用的,但它不会导致该类型符合等价类。这只意味着您可以评估item == item。但是,您不能调用items.contain(item),因为Itemable不符合等价性。您可以做的是调用items.contains{$0 == item},因为这只需要==函数,而不是等价的。当然,如果需要的话,可以为[Itemable]实现一个自定义的[Itemable]方法。但还是不能等量齐观。

对于您的例子,我相信您希望完全摆脱==,并使用以下方法:

代码语言:javascript
复制
guard let itemIndex = items.index(where: { $0.aProperty == item.aProperty }) else {

如果您经常这样做,当然可以在[Itemable]上添加一个扩展(未经测试):

代码语言:javascript
复制
extension Array where Element: Itemable {
    func index(of element: Element) -> Int? {
        firstIndex(where: { $0.aProperty == element.aProperty })
    }
}

那么你的原始代码就没问题了。

与您的问题有些无关:这可能是简化的代码,但是对于这种==的实现要非常小心。首先,==应该始终测试所有可见属性。例如,如果aProperty只是ID,那么这是实现==的危险方法。当两个条件相等时(在ObjC和Swift中),它们在所有上下文中都是可互换的。如果你曾经关心过你拥有哪一个,它们并不是真正的“平等”。

另外,当两个条件相等时,它们应该有相同的散列(如果它们是相等的,它们必须具有相同的散列)。

有关规则,请参阅符合“平等议定书”上的文档。虽然==在技术上并不意味着等同,但如果您的意思不是可等价物,那么使用它是令人困惑的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60360248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档