【问题标题】:Swift indexOf inconsistent behavior [duplicate]Swift indexOf不一致的行为[重复]
【发布时间】:2016-08-03 10:52:03
【问题描述】:

我似乎遇到了与 Swift 的 indexOf 函数不一致的行为。

Swift 中有两个indexOf 函数:
1.第一个以Equatable为参数:array.indexOf(obj)
2.第二种以匹配闭包为参数:array.indexOf{$0 == obj}

我有一个 NSObject 子类,为其定义了 == 运算符,即它符合 Equatable,因此,我假设这两个函数的工作方式完全相同(以闭包为例)。

但是,1st 方法的行为不一致,特别是在使用对象调用时它返回 nil,该对象的实例不存在于数组中。

为了说明问题,我提供了带有 cmets 的示例代码:

class EqObj: NSObject {
  let value: Int
  init(value: Int) {
    self.value = value
  }
}

func ==(lhs: EqObj, rhs: EqObj) -> Bool{
  return lhs.value == rhs.value
}

var array = [Obj(value: 1), Obj(value: 3), Obj(value: 5)]
var object = Obj(value: 5)

// returns nil, should return 2 - incorrect
array.indexOf(object) // Instance is not present
// returns 2, correct
array.indexOf(array.last!) // Instance is present
// returns 2, correct
array.indexOf{$0 == object} // Instance is not present, predicate
// returns non-empty array, correct
array.filter{$0 == object} // Instance is not present, predicate

这个问题只能在 NSObject 子类中重现。当我将 Obj: NSObject 更改为 Obj: Equatable 时,方法 indexOf() 完全按预期工作,即返回 2

问题是这是否可以被认为是一个错误?

我的假设是array.indexOf(object) 调用NSObjectisEqual 方法,而不是我重载的== 运算符。

我的解决方案: 我用array.indexOf{$0 == object}

【问题讨论】:

  • Obj 是如何定义的?
  • 为什么你认为 indexOf 应该使用你的重载运算符?这不是错误
  • @Lu_ 因为indexOf()Equatable 上运行。另一个 indexOf{} 适用于任何类型并关闭以比较两个实例。
  • @appzYourLife 只是EqObj: NSObject(不一致的行为)或EqObj: Equatable(预期的行为)
  • “我的假设是 array.indexOf(object) 调用了 NSObject 的 isEqual 方法”——确实如此,对于 NSObject 子类。

标签: arrays swift indexof nsobject equatable


【解决方案1】:

首先有了这个定义,我得到了不同的结果

class Obj: NSObject {
    let value: Int

    init(value:Int) {
        self.value = value
    }
}

func ==(lhs: Obj, rhs: Obj) -> Bool{
    return lhs.value == rhs.value
}

var array = [Obj(value: 1), Obj(value: 3), Obj(value: 5)]
var object = Obj(value: 5)

他们来了

您可以阅读以下每个结果后的原因

结果 #1

array.indexOf(object) // nil

在这种情况下使用 isEqual 方法,因此您只是比较内存地址。由于 object var 引用了数组内的对象 NOT,因此您将得到 nil 作为结果

结果 #2

array.indexOf(array.last!) // 2

再次使用isEqual。但是在这里,您将向 indexOf 传递对数组中最后一个对象的引用,因此它可以工作。

结果 #3

array.indexOf { $0 == object } // 2

在这里,您明确使用了您定义的 == 运算符,因此使用了 value 属性。

结果 #4

array.filter { $0 == object } // [{NSObject, value 5}]

再次使用== 运算符,然后使用value 属性检查是否相等。

【讨论】:

  • 结果与我的有何不同?它们完全一样。
  • 结果 3:当我获取索引 2 时,您说实例不存在。结果 4:当我获取过滤后的数组时,您说实例不存在
  • 我的意思是要检查的数组中不存在对象的特定实例。它是在var object = Object(value: 5) 中创建的单独实例。结果列在每行代码的上方。
  • @RichardTopchiy:那我们得到同样的结果,你可以在我的回答中找到原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 2019-02-27
  • 2016-07-04
  • 1970-01-01
相关资源
最近更新 更多