我在Swift中找到了一些令人惊讶的可选字典行为.
var foo:Dictionary<String, String>?
if (foo == nil) {
foo = ["bar": "baz"]
}
else {
// Following line errors with "'Dictionary<String, String>?' does
// not have a member named 'subscript'"
foo["qux"] = "quux"
}
Run Code Online (Sandbox Code Playgroud)
我已经玩了很多,试图弄清楚我可能会遗漏什么,但似乎没有任何东西使这个代码按预期工作,使得字典不是可选的.我错过了什么?
我能得到的最接近的是以下,但当然这很荒谬.
var foo:Dictionary<String, String>?
if (foo == nil) {
foo = ["bar": "baz"]
}
else if var foofoo = foo {
foofoo["qux"] = "quux"
foo = foofoo
}
Run Code Online (Sandbox Code Playgroud)
mat*_*att 31
当您意识到可选字典不是字典时,灯泡时刻就会出现.一个可选的东西不是那个东西!这是一个可选的!! 这就是全部.可选本身就是一种类型.一个可选项只是一个枚举,包含可能的案例nil和一些值.包装的值是一个完全不同的对象,存储在里面.
所以任何东西都不会像那种东西那样.不是那个东西!这只是一个选择.解决问题的唯一方法是解开它.
隐式解包的Optional也是如此; 不同之处仅在于隐式展开的Optional愿意"自动"生成(公开)包装值.但它实际上仍然是包装好的.并且,正如布莱恩·陈所观察到的那样,它是不可改变地包裹着的; 可选项只是为您举办 - 它没有给您一个可以玩的地方.
你可以使用这段代码
if var foofoo = foo {
foofoo["qux"] = "quux"
foo = foofoo
} else {
foo = ["bar": "baz"]
}
Run Code Online (Sandbox Code Playgroud)
用这个代码
var foo:Dictionary<String, String>? = Dictionary()
foo[""]=""
error: 'Dictionary<String, String>?' does not have a member named 'subscript'
foo[""]=""
^
Run Code Online (Sandbox Code Playgroud)
错误消息对我Dictionary<String, String>?没有实现subscript方法是有意义的,所以你需要在能够使用之前解开它subscript.
在可选上调用方法的一种方法是使用!ie foo![""],但是......
var foo:Dictionary<String, String>? = Dictionary()
foo![""]=""
error: could not find member 'subscript'
foo![""]=""
~~~~~~~~^~~
Run Code Online (Sandbox Code Playgroud)
而
var foo:Dictionary<String, String>? = Dictionary()
foo![""]
Run Code Online (Sandbox Code Playgroud)
作品
有趣的是这些代码无法编译
var foo:Dictionary<String, String>! = Dictionary() // Implicitly unwrapped optional
foo[""]=""
error: could not find an overload for 'subscript' that accepts the supplied arguments
foo[""]=""
~~~~~~~^~~
Run Code Online (Sandbox Code Playgroud)
var foo:Dictionary<String, String>! = Dictionary() // Implicitly unwrapped optional
foo.updateValue("", forKey: "")
immutable value of type 'Dictionary<String, String>' only has mutating members named 'updateValue'
foo.updateValue("", forKey: "")
^ ~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
最后一条错误信息最有意思,它是说Dictionary是不可变的,所以updateValue(forKey:)(变异方法)不能被调用
所以发生的事情可能是Optional<>存储Dictionary为不可变对象(带let).所以即使Optional<>它是可变的,你也不能Dictionary直接修改底层对象(不重新分配Optional对象)
这段代码有效
class MyDict
{
var dict:Dictionary<String, String> = [:]
subscript(s: String) -> String? {
get {
return dict[s]
}
set {
dict[s] = newValue
}
}
}
var foo:MyDict? = MyDict()
foo!["a"] = "b" // this is how to call subscript of optional object
Run Code Online (Sandbox Code Playgroud)
这引出了另一个问题,为什么Array和Dictionary价值类型(结构)?对面NSArray和NSDictionary哪个是参考类型(类)
| 归档时间: |
|
| 查看次数: |
19516 次 |
| 最近记录: |