在Swift 2.1中,可以编译以下代码。
let a = [1: [1]]
a == [1: [1]]
但是,以下代码无法编译。
let a = [1: [1]]
let b = [1: [1]]
a == b // => binary operator '==' cannot be applied to two '[Int : Array<Int>]' operands
如何理解这种行为?
答案 0 :(得分:5)
有一个==
运算符比较两个Swift词典,不过它
要求值类型为Equatable
:
public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool
问题是即使对于等同类型T
,Array<T>
也不符合<{1}}协议。例如,参见
Why can't I make Array conform to Equatable?进行讨论
在Apple开发者论坛中。
这解释了为什么
Equatable
无法编译。在你的第一个例子中
let a = [1: [1]]
let b = [1: [1]]
a == b // => binary operator '==' cannot be applied to two '[Int : Array<Int>]' operands
编译器非常聪明,可以将文字数组let a = [1: [1]]
a == [1: [1]]
作为一个
[1]
字面意思,使用
NSArray
这个编译因为所有继承自的类
extension NSArray : ArrayLiteralConvertible {
/// Create an instance initialized with `elements`.
required public convenience init(arrayLiteral elements: AnyObject...)
}
符合NSObject
。
这是一个更简单的例子,展示了同样的问题:
Equatable
可以看出, literal 数组被转换为了一些子类
传递给期望func foo<T : Equatable>(x : T) {
print(x.dynamicType)
}
let ar = [1, 2, 3]
// This does not compile:
foo(ar) // error: cannot invoke 'foo' with an argument list of type '([Int])'
foo([1, 2, 3]) // Output: __NSArrayI
参数的函数时,NSArray
类集群。
另请注意,如果您只导入Swift,但不导入Foundation(或UIKit,...),那么
Equatable
也不是你的第一个例子编译。