Swift奇怪的'=='与Dictionary的行为

Har*_*ada 1 swift swift2

在Swift 2.1中,可以编译以下代码.

let a = [1: [1]]
a == [1: [1]]
Run Code Online (Sandbox Code Playgroud)

但是,以下代码无法编译.

let a = [1: [1]]
let b = [1: [1]]
a == b // => binary operator '==' cannot be applied to two '[Int : Array<Int>]' operands
Run Code Online (Sandbox Code Playgroud)

怎么理解这种行为?

Mar*_*n R 5

有一个==运算符比较两个Swift词典,但它要求值类型为Equatable:

public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool
Run Code Online (Sandbox Code Playgroud)

问题是,即使是equatable类型T, Array<T> 不符合Equatable协议.请参阅示例 为什么我不能使Array符合Equatable?在Apple开发者论坛中进行讨论.

这解释了原因

let a = [1: [1]]
let b = [1: [1]]
a == b // => binary operator '==' cannot be applied to two '[Int : Array<Int>]' operands
Run Code Online (Sandbox Code Playgroud)

不编译.在你的第一个例子中

let a = [1: [1]]
a == [1: [1]]
Run Code Online (Sandbox Code Playgroud)

使用时,编译器非常聪明地将文字数组[1]作为 NSArray文字

extension NSArray : ArrayLiteralConvertible {
    /// Create an instance initialized with `elements`.
    required public convenience init(arrayLiteral elements: AnyObject...)
}
Run Code Online (Sandbox Code Playgroud)

这个编译因为所有继承自的类都 NSObject符合Equatable.

这是一个更简单的例子,展示了同样的问题:

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
Run Code Online (Sandbox Code Playgroud)

可以看出,当传递给期望参数的函数时,文字数组被转换为NSArray类集群的某个子 类Equatable.

另请注意,如果您只导入Swift,但不导入Foundation(或UIKit,...)

foo([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

也不是你的第一个例子编译.