尝试使用Equatable协议中定义的'=='运算符比较AnyObject类型的两个对象会导致Swift中出现编译错误.有没有人找到比较这些对象的方法,而不知道可以用于向下转换的真实对象类型?
这个问题的背景是我有一个字典Dictionary <String,AnyObject>,其中值应该通过下标提供,然后在某些时候我需要比较字典中的值以确保它们是唯一的.
编辑 这是一个演示该问题的片段.
@objc(FooObject)
public class FooObject: NSManagedObject {
@NSManaged public var properties: Dictionary<String, AnyObject>
public subscript(property: String) -> AnyObject? {
get {
return properties[property]
}
set(newValue) {
for propertyValue in properties.values {
if propertyValue == newValue { // This line is not compiling: Cannot invoke '==' with AnyObject
println("Values in are expected to be unique!")
// Throw an exception here ...
}
}
properties[property] = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,在类定义中声明的类似<T:Equatable>的泛型并用作字典的值类型将无法解决问题,因为它不能与NSManagedObject子类一起使用.
小智 22
使用Swift文档中的===运算符:
Swift还提供了两个标识运算符(===和!==),用于测试两个对象引用是否都引用同一个对象实例.
我不认为这是可能的.问题是Equatable是用一个方法定义的
func ==(a: T, b: T)
并且在编译时没有办法,编译器可以找到正确的函数(因为它不提前知道类型).
你能做到这一点的唯一方法就是你对比较的类型有所了解.然后你可以具体地为每种类型调用适当的相等函数:
func compare(a: AnyObject, b: AnyObject) {
if let va = a as? Int, vb = b as? Int {if va != vb {return false}}
else if let va = a as? String, vb = b as? String {if va != vb {return false}}
else if let va = a as? Bool, vb = b as? Bool {if va != vb {return false}}
...
else {
// not a type we expected
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,例如,C#通过将IComparable接口定义为具有方法来解决这个问题:
int CompareTo(Object obj)
这允许每个IComparable对象将自己与任何其他对象进行比较(但函数必须始终在此处进行自己的类型检查,以确保obj其类型正确).
小智 1
看一下实现:
/// Returns true if these arrays contain the same elements.
func ==<T : Equatable>(lhs: [T], rhs: [T]) -> Bool
Run Code Online (Sandbox Code Playgroud)
这意味着编译器需要知道左侧和右侧参数必须是相同的类型。所以你正在实现的函数应该是这样的:
func compareFunc <T: Equatable>(par1: T, par2: T) {
...
if par1 == par2 {
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
编辑:
你的字典应该是这样的:
func compareFunc <T: Equatable>(dic1: [String : T], dic2: [String : T]) {
...
if dic1[yourKey] == dic2[yourKey] {
...
}
...
}
Run Code Online (Sandbox Code Playgroud)
编辑2:
一个例子:
func compareFunc <T: Equatable>(dic1: [String : T], dic2 : [String : T]) -> Bool {
return dic1["key"] == dic2["key"]
}
compareFunc(["key": "value"], ["key": "value"])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15918 次 |
| 最近记录: |