无法使用类型 '([Foo], Foo)' 的参数列表调用'contains'



我正在尝试在 swift 中使用 contains 函数来查看我的对象是否在类型化数组中,但我得到:

无法使用类型为"([Foo], Foo)"的参数列表调用"包含"

class Foo {
}
let foo = Foo()
let foos = [Foo(), Foo()]
contains(foos, foo)

为什么会这样?

更新 #1

我已经实现了==功能,但仍然收到相同的错误。我这样做不当吗?

class Foo {}
func ==(lhs: Foo, rhs: Foo) -> Bool {
    return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}
let foo = Foo()
let foos = [Foo(), Foo()]
contains(foos, foo)

不会自动从基类继承任何相等逻辑,因此您需要显式并具有符合Equatable协议Foo

实际上,编译器可以从该类声明中派生的唯一合理的平等是标识,您可能不希望这样。

请注意,

class Foo {}

class Foo : NSObject { }

通过从NSObject继承,您还可以继承 isEqual 的默认实现,这提供了对象标识相等。


关于上次更新,您只缺少类定义中的Equatable协议。以下编译就好了

class Foo : Equatable {}
func ==(lhs: Foo, rhs: Foo) -> Bool {
    return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
    // or simply
    // return lhs === rhs
}
let foo = Foo()
let foos = [Foo(), Foo()]
contains(foos, foo)

或者干脆从 NSObject 继承,这已经提供了身份平等

class Foo : NSObject {}
let foo = Foo()
let foos = [Foo(), Foo()]
contains(foos, foo)

contains的唯一函数签名是:

func contains<S : SequenceType where S.Generator.Element : Equatable>(seq: S, x: S.Generator.Element) -> Bool

Foo不是Equatable,所以它与这个签名不匹配。

另请注意,总有一种方法可以检查数组中类的实例,即使您没有实现平等协议或继承自NSObject。您可以使用reduce执行以下操作:

class MyClass { }
let myClass1 = MyClass()
let myArray = [myClass1]
let lookForMyClass1 = myArray.reduce(false) { $0 || $1 === myClass1 }
println(lookForMyClass1)  // Outputs: true

你可以概括它以在任何SequenceType中查找任何类对象,方法是用如下内容重载contains

func contains<T: AnyObject, S: SequenceType where T == S.Generator.Element>(#haystack: S, #needle: T) -> Bool {
    return reduce(haystack, false) { $0 || $1 === needle }
}

现在你可以像这样调用contains

let searchForMyClass1 = contains(haystack: myArray, needle: myClass1)
println(searchForMyClass1)  // Output: true

相关内容

最新更新