【发布时间】:2015-01-03 16:22:22
【问题描述】:
我正在尝试实现Dictionary 扩展,并且我想处理可选值。但无论我做什么,如果我在 [String: String?] 字典上使用我的方法,它就无法选择性地绑定该值。你如何为一个优雅地处理可选值的字典编写一个扩展?
考虑以下扩展:
extension Dictionary {
func someMethod() {
for (key, value) in self {
if let valueString = value as? String {
println(" \(key) = \(valueString)")
} else {
println(" \(key) = \(value) cannot be cast to `String`")
}
}
}
}
所以考虑下面的代码:
let dictionary: [String: AnyObject?] = ["foo": "bar"]
dictionary.someMethod()
它奇怪地报告
foo = Optional(bar) cannot be cast to `String`
我可以编写一个非扩展方法来处理具有可选值的字典参数,但不知道如何将其作为Dictionary 的扩展。
【问题讨论】:
-
我可以解释为什么它不像你预期的那样工作。当应用于 Optional 时,
as、is、as?和==(以及其他比较器)具有特殊含义:它们应用于事物包装。if let valueString = value as? String没有按照您的预期执行的原因是,在编译时我们不知道value是 一个 Optional,因此我们不使用特殊含义as应用于 Optional。我们尝试将 Optional itself 转换为 String,当然失败了;你不能将 Optional itself 投射到任何东西上。 -
正如您自己所说,我相信,Swift 似乎邀请使用实例方法,但实际的力量在于顶级全局函数,因为它们允许您构建一个通用约束,只允许通过网格的正确类型,因为它是。字典是泛型的,你不能给泛型添加更多的约束,所以你永远不能用扩展中的实例方法来做到这一点。