如何制作包含特定值的 Swift 字典?

Posted

技术标签:

【中文标题】如何制作包含特定值的 Swift 字典?【英文标题】:How to make a Swift Dictionary that hold specific values? 【发布时间】:2016-01-18 07:42:34 【问题描述】:

通常我会这样创建我的 swift 字典:

var myDict: [String: String]

但是我如何创建一个可以作为值的字典,只有一个字符串或一个布尔值?

如果我像下面的代码那样声明字典

var myDict: [String: Any]

那么我的数组现在可以容纳任何我不想要的对象。有没有办法声明 Dictionary 只接受 StringBool 值类型?

[编辑] - 用例是:我需要一个键和值的字典。但我只想将值限制为字符串或布尔值。没有其他的。目标是最终使用此 Dictionary 转换为 JSON 格式以发送到某个服务器。根据下面的答案,我唯一的选择是枚举还是类/结构?我想知道是否有办法使 Bool 和 String 符合某种协议?

这个想法可能是这样声明字典

var myDict : [String: stringOrBool]

然后像这样填写字典

myDict["firstKeyStringValue"] = "my first string value" // This should work
myDict["firstKeyBoolValue"] = true // This should work
myDict["someOtherKey"] = 123 // This should fail

编辑 2 根据下面的答案,我选择了协议方法,因为它在语法上更容易。但是正如下面cmets中提到的Catfish,它可能会占用更多内存。

【问题讨论】:

考虑使用自定义的structclass 而不是Dictionary 为什么要这样做?你的用例是什么?我们也许可以一起提出更好的设计模式。 @davecom 用例是我需要一个键和值的字典。但我只想将值限制为字符串或布尔值。没有其他的。目标是最终使用此 Dictionary 转换为 JSON 格式。 【参考方案1】:
protocol StringOrBool 


extension Bool: StringOrBool 


extension String: StringOrBool 


var myDict: [String : StringOrBool] = [:]

myDict["testKey"] = "sd"   // works
myDict["testKey2"] = false // works
myDict["testKey2"] = 2     // fails

【讨论】:

你的解决方案是绝对正确的,你有我的支持。只有一个建议:协议的名称应该以 大写 字母开头。所以StringOrBool 而不是stringOrBool【参考方案2】:

你可以这样做

enum StuffThatGoesInMyDictionary 
    case Text(String)
    case Boolean(Bool)

然后让你的字典成为

var myDict: [String : StuffThatGoesInMyDictionary]

【讨论】:

好的,我有点困惑。我使用了那个枚举。然后我做了 --> myDict["testKey"] = "testValue"。但它给了我错误“无法将类型“String”的值分配给类型“StuffThatGoesInMyDictionary”。我不熟悉该枚举语法。你如何使用它? 因为你会这样做:让 foo = myDict["testKey"] 然后用 2 种情况切换 foo:.Text 和 .Boolean 是的,没有自动转换。您需要使用开关检查给定值实际上是哪些可能性。同理,在放入的时候需要构造其中一种情况,比如myDict["testKey"] = .Text("hello") @Catfish_Man:非常好的解决方案。特别是因为它确实会迫使您选择一种(并且只有一种)类型。 @Catfish_Man 嗨,根据投票,您的答案(或appzYourLife 通用答案)似乎是正确的。但是,最后一个问题,看起来pathTheCode 的答案更容易输入。他的方法有问题吗?如果他的答案不好,我会选择你的答案。【参考方案3】:

此解决方案基于 Catfish_Man 的回答,我只是将其设为通用。

有了这个枚举

enum XORWrapper<A,B> 
    case Value0(A)
    case Value1(B)

您可以声明一个包含 2 个泛型类型的值(例如 StringBool)的值。

let boolOrString: XORWrapper<String, Bool>

然后你可以用第一个类型填充它(例如String

boolOrString = XORWrapper.Value0("Hello world")

或与第二个(例如Bool

boolOrString = XORWrapper.Value1(true)

【讨论】:

嗨,你的回答似乎是 catfish_man 的一个很好的通用版本。 patchTheCode 的答案会很糟糕吗?我正在考虑它,因为它的代码更少并使用正常语法向字典添加值,但我不确定扩展是否会产生不良副作用 @Jay:catfish_manPatchTheCode 的两个答案都是正确的,所以选择你最熟悉的那个。

以上是关于如何制作包含特定值的 Swift 字典?的主要内容,如果未能解决你的问题,请参考以下文章

检查字典是不是包含 Swift 中的值

Swift 在结构中制作 init 字典

搜索特定值的嵌套字典列表[重复]

在 Swift 中使用协议作为类型时出错

如何使用Python搜索字典值是不是包含某些字符串

如何在swift 3中找到数组包含字典的数组索引?