我正在尝试在 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