问题描述
在Swift 2.1中,可以编译以下代码.
In Swift 2.1, following code can be compiled.
let a = [1: [1]]
a == [1: [1]]
但是,以下代码无法编译.
However, following code cannot be compiled.
let a = [1: [1]]
let b = [1: [1]]
a == b // => binary operator '==' cannot be applied to two '[Int : Array<Int>]' operands
如何理解这种行为?
推荐答案
有一个==
运算符比较两个Swift字典,但是它要求值类型为Equatable
:
There is a ==
operator comparing two Swift dictionaries, however itrequires that the value type is Equatable
:
public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool
问题在于,即使对于等于类型的T
,Array<T>
也不符合 协议.例如看为什么我不能使Array符合Equatable?进行讨论在苹果开发者论坛中.
The problem is that even for equatable types T
, Array<T>
does not conform to the Equatable
protocol. See for exampleWhy can't I make Array conform to Equatable? for a discussionin the Apple developer forum.
这说明了原因
let a = [1: [1]]
let b = [1: [1]]
a == b // => binary operator '==' cannot be applied to two '[Int : Array<Int>]' operands
不编译.在第一个示例中
does not compile. In your first example
let a = [1: [1]]
a == [1: [1]]
编译器非常聪明,可以将文字数组[1]
用作NSArray
文字,使用
the compiler is so smart to take the literal array [1]
as anNSArray
literal, using
extension NSArray : ArrayLiteralConvertible {
/// Create an instance initialized with `elements`.
required public convenience init(arrayLiteral elements: AnyObject...)
}
这会编译,因为所有类都继承自NSObject
符合Equatable
.
And this compiles because all classes inheriting fromNSObject
conform to Equatable
.
这是一个更简单的示例,它演示了相同的问题:
Here is a simpler example demonstrating the same issue:
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
正如人们所看到的, literal 数组被转换为NSArray
类簇,当传递给需要Equatable
自变量的函数时.
As one can see, the literal array is converted to some subclass of theNSArray
class cluster when passed to a function expecting an Equatable
argument.
还请注意,如果您仅导入Swift,但不导入Foundation(或UIKit,...),则都不导入
Note also that if you only import Swift, but not Foundation (or UIKit, ...) then neither
foo([1, 2, 3])
您的第一个示例也不会编译.
nor your first example compiles.
这篇关于带有字典的Swift奇怪的'=='行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!