17

我知道单个感叹号的定义,但是两个?

我今天在编码,编译器“强迫”我再添加一个!对我的句子:

mySignal.subscribeNext({
        (value: AnyObject!) -> () in
        let list: RACSequence = value["myObject"]!!.rac_sequence
        ...

如果我只用一个!标记,项目没有编译,给我错误:“可选类型'AnyObject?'的值?没有打开;你是不是要使用“!” 或者 '?'?” 那我再加一个!一切正常。

Swift中的两个感叹号是什么意思?

4

2 回答 2

9

您将 an 存储AnyObject!在字典中,因此您将可选存储为值。字典下标总是返回你存储的值的一个可选值,所以你得到一个可选的可选值,这就是为什么你需要两个 ! 来解开它两次。

于 2015-07-17T02:31:25.037 回答
6

这是使用 AnyObject 类型而不是显式字典类型的奇怪工件。通常,像 Optional 这样的 monad(感谢 user2864740)实现了一个带有像Optional<T>.bind(f: T -> Optional<U>) -> Optional<U>.

这使得当您访问可选值的可选成员时,您不会得到一个双重可选,您必须像洋葱一样打开每一层访问。

如果你用一个显式字典做一个类似的例子,你会发现结果类型只是一个 Optional 层:

import UIKit

let anyDict: AnyObject? = ["foo" : 34, "bar" : 13]
let anyElement = anyDict?["foo"]
print(anyElement) // Optional(Optional(34))

let dict: [String : Int]? = ["foo" : 34, "bar" : 13]
let element = dict?["foo"]
print(element) // Optional(34)

目前尚不清楚为什么 AnyObject 会发生这种情况,但我不认为这是预期的行为。

于 2015-07-17T03:58:31.163 回答