覆盖Swift字典创建不允许nil

时间:2016-12-12 18:58:45

标签: swift dictionary

在这个游乐场示例中,我希望找到一个扩展名,删除我在创建字典时所添加的任何内容。

u'â'

在上面的代码中,当前日志是

var someValue: String?

if false {
   someValue = "test"
}

var dict = ["key": "value",
            "key2": someValue]
print("\(dict)")
dict["key3"] = nil

print("\(dict)")

key3永远不会被添加,因为setting = nil告诉它被删除。我想将这个功能添加到字典的初始创建中,但尚未找到有效的解决方案。

工作解决方案将导致以下打印输出

[AnyHashable("key2"): nil, AnyHashable("key"): Optional("value")]
[AnyHashable("key2"): nil, AnyHashable("key"): Optional("value")]

2 个答案:

答案 0 :(得分:0)

在Swift The Programming Language Book中,我引用:

  

您可以使用下标语法通过为该键指定值nil来从字典中删除键值对

他们说在删除对时将值赋给nil,但在初始化字典时没有提到,所以我认为它无效。

如果你真的需要这样做,我建议在初始化字典后为你做一些逻辑,比如:

for (key, value) in dict {
    if value == nil {
        dict[key] = nil
    }
}

答案 1 :(得分:0)

这在Swift中是无法解决的。写它的正确方法是:

var dict = ["key": "value"]
if false {
    dict["key2"] = "test"
}

Swift没有提供你所描述的那种语法,并试图强制它将打破类型并创建错误的情况。不要尝试创建[AnyHashable: Any?]。这是一个完全被破坏的类型,它会烧毁你(Any?完全被打破,因为OptionalAny,任何东西都可以隐式变为可选,所以它变成了一个奇怪的递归兔子洞)。如果您必须与[AnyHashable: Any]联系,NSDictionary是可以接受的,但一般情况下应该强烈避免,并且仅限于您需要的地方。

请注意,这在ObjC中更为严重(你可以编写这种东西,但它会崩溃或截断你的字典,或者其他一些奇怪的bug),所以至少我们正在取得一些进展。

在很多情况下,当我看到人们遇到这个问题时,这是因为他们首先过度使用了选项。在您的user.name示例中,为什么name首先是可选的? nil和“”之间有什么区别吗?如果没有(并且通常没有),那么只需使name非可选(在ObjC中不可空)并将其默认为空并且许多问题都会消失。具有相同值的两个版本(即nil和“”具有相同含义)表示类型问题,而不是语法问题。

如果你想通过一个可以处理键/值的快速扩展来简化语法?像这样的对:

extension Dictionary {
    init(keyOptionalPairs: [(Key, Value?)]) {
        var d: [Key: Value] = [:]
        for (key, value) in keyOptionalPairs {
            d[key] = value
        }
        self = d
    }
}

let keyValues: [(String, String?)] = [
    ("key", "value"),
    ("key2", nil)
]

let dict = Dictionary(keyOptionalPairs: keyValues)

但请注意,词典是[String: String],而不是[String: String?]。这是故意的。

与语法相比,它只添加了一组parens。但与非花哨的版本相比,它并不漂亮,但非常简单。

let dict: [String: String] = {
    var d: [String: String] = [:]
    d["key"] = "value"
    d["key2"] = nil
    return d
}()