【问题标题】:Binary operator '==' cannot be applied to two operands二元运算符“==”不能应用于两个操作数
【发布时间】:2016-04-10 23:45:01
【问题描述】:

我有一个使用协议Equatable 的课程。该类如下所示:

class Item: Equatable {

    let item: [[Modifications: String]]

    init(item: [[Modifications: String]]) {
        self.item = item
    }
}

func ==(lhs: Item, rhs: Item) -> Bool {
    return lhs.item == rhs.item
}

但这给了我错误(见标题)。属性item 之前是[[String: String]],没有问题,我不知道如何解决这个问题。我尝试在整个 SO 上进行谷歌搜索和搜索,但没有运气..

枚举只是一个简单的基础:

enum Modifications: Int {
    case Add    = 1
    case Remove = 2
    case More   = 3
    case Less   = 4
}

【问题讨论】:

  • 也许您需要将== 函数放在类定义中,以使其符合Equatable 协议。
  • @MikeAtNobel 不,实施的地方很好。
  • 修改是否符合 Equatable?既然你在你的字典数组中使用它,我可以理解为什么它需要是相等的才能让你的项目是相等的
  • 当它是[[String: String]] 时没有问题,所以应该可以比较二维字典。 @ milo526:因为枚举具有原始类型值,所以如果我正确,它会自动变得相等。 @Leo Dabus:是的,我正在尝试另一种方式,但如果它是一系列字典会容易得多。
  • 它看起来与stackoverflow.com/questions/33377761/… 非常相似:您可以将[Modifications: String] 的两个实例与== 进行比较,但[Modifications: String] 不符合Equatable。因此,== 没有为这些字典的 array 定义。 – 我的猜测是这适用于 [[String: String]],因为 [String: String] 可以桥接到 NSDictionary(又是 Equatable)。

标签: swift enums equatable


【解决方案1】:

更新:SE-0143 Conditional conformances 已在 Swift 4.2 中实现。

因此,您的代码现在可以编译了。如果您将 Item 定义为 struct

struct Item: Equatable {
    let item: [[Modifications: String]]

    init(item: [[Modifications: String]]) {
        self.item = item
    }
}

然后编译器会自动合成== 运算符, 比较SE-0185 Synthesizing Equatable and Hashable conformance


(Swift 4.1 之前的答案:)

问题是即使为字典类型定义了== [Modifications: String],该类型不符合 Equatable。因此数组比较运算符

public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool

不能应用于[[Modifications: String]]。

== for Item 的一个可能的简洁实现是

func ==(lhs: Item, rhs: Item) -> Bool {
    return lhs.item.count == rhs.item.count 
           && !zip(lhs.item, rhs.item).contains {$0 != $1 }
}

您的代码编译为[[String: String]] – 如果基金会 框架被导入,正如@user3441734 正确所说的那样——因为然后[String: String] 会自动转换为NSDictionary,它符合 Equatable。这是该声明的“证据”:

func foo<T : Equatable>(obj :[T]) {
    print(obj.dynamicType)
}

// This does not compile:
foo( [[Modifications: String]]() )

// This compiles, and the output is "Array<NSDictionary>":
foo( [[String: String]]() )

【讨论】:

  • 很好的解释,很高兴知道为什么它对[[String: String]] 有效。将此标记为已回答,因为答案看起来更优雅。现在我只需要弄清楚如何忽略字典的顺序。
  • @MartinR: user3441734 在 cmets 中对我下面的回答指出 Dictionary 类型不符合协议 Equatable。您不知道为什么我们仍然可以像上面的$0 != $1(或下面我的解决方案中的lhsDict != rhs.item[i])那样“立即”比较它们的原因吗?是不是很像你上面提到的那种自动转换?
  • @dfri:有一个 public func ==&lt;Key : Equatable, Value : Equatable&gt;(lhs: [Key : Value], rhs: [Key : Value]) -&gt; Bool 运算符:如果键和值类型都是 Equatable,您可以将字典与 == 进行比较。这与数组相同:如果元素类型为 Equatable,您可以将它们与 == 进行比较。
  • @MartinR 请注意,在 Foundation 的帮助下可以使用“免费桥接”。顺便说一句,你的解释很清楚!我希望我有相同的属性来解释我的想法或想法。不幸的是,我没有...
  • @user3441734:你完全正确,这是一个很好的观点。
【解决方案2】:

在Item 对象的== 函数中,您需要进一步指定如何比较两种类型的字典数组(特别是两种类型的[[Modifications: String]])。

以下工作解决方案逐个元素比较您的 item 数组(字典逐个字典),并且 == 仅在数组包含相同数量的字典并且所有条目都相同且排序时返回 true字典数组中的相同方式

func ==(lhs: Item, rhs: Item) -> Bool {

    if lhs.item.count == rhs.item.count {
        for (i, lhsDict) in lhs.item.enumerate() {
            if lhsDict != rhs.item[i] {
                return false
            }
        }
        return true
    }
    else {
        return false
    }
}

class Item : Equatable {

    let item: [[Modifications: String]]

    init(item: [[Modifications: String]]) {
        self.item = item
    }
}

您可能希望将其修改为您真正想要用于比较的形式,但我希望您能理解它的要点。

还要注意,如果在操场上进行测试,重要的是你的 == 函数定义 func ==(lhs: Item, rhs: Item) -&gt; Bool { .. 应该在你的类定义之前,否则你会得到一个不符合 @987654329 的错误@。

【讨论】:

  • 谢谢,这确实使Item 具有可比性。我希望有更简单的东西,但我想我必须遍历数组并比较它们。
  • @HennyLee 也许你能想出一个更好的解决方案,这主要向你展示如何实现一个工作的例子。例如。在上述数组长度相同的情况下,使用 zip 和 map 可能会将 for 循环压缩为一行。
  • 一个 Swift 数组不符合 Equatable 协议。因此,您有责任使 Array 符合 Equatable 协议。你将如何做,取决于你。符合 Equatable 意味着定义了运算符 ==。如果需要,它可以简单地返回 true :-) 方式,如何检查 [Modifications:String] 类型的实例完全由您负责。
  • @user3441734 你说得对,请注意[Modifications:String] 类型的两个字典与== 直接可比(因为字典是相等的):这里的问题是这些字典的数组非基本键类型(正如 Martin R 在他的回答中所涵盖的那样)。
  • @dfri 你确定 Dictionary 符合 Equatable 吗?
猜你喜欢
  • 2015-09-01
  • 2017-11-22
  • 2018-06-23
  • 2023-03-10
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多