如何制作包含特定值的 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 只接受 String
和 Bool
值类型?
[编辑] - 用例是:我需要一个键和值的字典。但我只想将值限制为字符串或布尔值。没有其他的。目标是最终使用此 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,它可能会占用更多内存。
【问题讨论】:
考虑使用自定义的struct
或class
而不是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 个泛型类型的值(例如 String
和 Bool
)的值。
let boolOrString: XORWrapper<String, Bool>
然后你可以用第一个类型填充它(例如String
)
boolOrString = XORWrapper.Value0("Hello world")
或与第二个(例如Bool
)
boolOrString = XORWrapper.Value1(true)
【讨论】:
嗨,你的回答似乎是 catfish_man 的一个很好的通用版本。 patchTheCode 的答案会很糟糕吗?我正在考虑它,因为它的代码更少并使用正常语法向字典添加值,但我不确定扩展是否会产生不良副作用 @Jay:catfish_man 和 PatchTheCode 的两个答案都是正确的,所以选择你最熟悉的那个。以上是关于如何制作包含特定值的 Swift 字典?的主要内容,如果未能解决你的问题,请参考以下文章