我正在尝试在swift中使用contains
函数来查看我的对象是否在一个类型化数组中,但我得到了:
无法使用Type'([Foo],Foo)'的参数列表调用'contains'
class Foo {
}
let foo = Foo()
let foos = [Foo(), Foo()]
contains(foos, foo)
为什么会这样?
我已经实现了==
函数,但我仍然遇到同样的错误。我这样做不正确吗?
class Foo {}
func ==(lhs: Foo, rhs: Foo) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}
let foo = Foo()
let foos = [Foo(), Foo()]
contains(foos, foo)
答案 0 :(得分:5)
类不会自动从基类继承任何相等逻辑,因此您需要明确并使Foo
符合Equatable
协议。
实际上,编译器可以从该类声明中获得的唯一明智的相等是身份,你可能不希望这样。
请注意
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)
答案 1 :(得分:2)
contains
的唯一功能签名是:
func contains<S : SequenceType where S.Generator.Element : Equatable>(seq: S, x: S.Generator.Element) -> Bool
Foo
不是Equatable
,因此它与此签名不匹配。
答案 2 :(得分:0)
另请注意,即使您尚未实现等同协议或从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