双重惊叹!!在 Swift 中标记?

Posted

技术标签:

【中文标题】双重惊叹!!在 Swift 中标记?【英文标题】:Double exclamation !! mark in Swift? 【发布时间】:2015-07-17 02:22:41 【问题描述】:

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

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

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

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

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

代码没有“将 AnyObject! 存储在字典中”——代码下标为 AnyObject! 类型的值。不清楚为什么要下标到 AnyObject!一开始是可能的,但是在任何 API 中,双重选项可能都不是预期的结果(请参阅下面的帖子)。 我今天在这里遇到了同样的情况:appDelegate.window!!.rootViewController = rootNavigationController 所以它似乎与字典无关。【参考方案2】:

这是使用 AnyObject 类型而不是显式字典类型的奇怪工件。通常,a monad like Optional(感谢 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 会发生这种情况,但我不认为这是预期的行为。

【讨论】:

我已将此代码粘贴到 Playground 中,但在使用 Swift 2.0 时出现无法将 [String: Int] 类型的值转换为指定类型 AnyObject。 这很奇怪。这个例子是基于 Swift 1.2 编写的,但我在 Xcode 7 beta 6 中使用 Swift 2 得到了相同的结果。 对不起,我忘了加import UIKit,我猜你应该在sn-p的开头加上这行,如果你把println改成print就好了。

以上是关于双重惊叹!!在 Swift 中标记?的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4553 约会安排(线段树区间合并+双重标记)

在 Swift 中保存 UITableViewCell 复选标记选择

如何在 Swift 中保存复选标记?

如何在 swift/iOS 中更新谷歌地图标记位置

Swift:如何在 UITableView 中定位标记的 UITextView?

如何在 Swift 2.0 中的 TableView 中获取选中标记的项目