本文介绍了带有字典的Swift奇怪的'=='行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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

问题在于,即使对于等于类型的TArray<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奇怪的'=='行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-14 12:44