我在Swift中有一个需要能够处理多种类型的函数。具体来说,它需要能够解析Dicts和Strings。
我遇到的问题是Dicts可能有几种类型,具体取决于它们的来源。因此,我可以获得[String:Any]
或[String:String]
(来自Swift)或[String:AnyObject]
(来自objc)。顶级解析函数使用Any
,然后测试特定类型并尝试解析它们。
首先我尝试测试if let dict = object as? [String:Any]
,但如果我传入其他类型[String:AnyObject]
或[String:String]
则失败。所以我尝试测试每种类型:
func parseLink(object: Any) {
if let dict = object as? [String:Any] {
return self.parseDict(dict)
} else if let dict = object as? [String:AnyObject] {
return self.parseDict(dict)
} else if let dict = object as? [String:String] {
return self.parseDict(dict)
} else if let string = object as? String {
return parseURL(string)
}
}
func parseDict(dict: [String:Any]) { ..... }
所以我创建了一些单元测试来测试行为:
func testDictTypes() {
let testDict: [String:Any] = [ "orgId" : "123456789" ]
let link = OrgContextLinkParser().parseLink(testDict)
XCTAssertNotNil(link)
let testDict1: [String:AnyObject] = [ "orgId" : "123456789" ]
let link2 = OrgContextLinkParser().parseLink(testDict1)
XCTAssertNotNil(link2)
let testDict3: [String:String] = [ "orgId" : "123456789" ]
let link3 = OrgContextLinkParser().parseLink(testDict3)
XCTAssertNotNil(link3)
}
这一切都编译得很好,但如果传入[String:AnyObject]
,我会遇到致命的运行时错误。这很麻烦,因为Swift的类型系统应该可以防止这类错误,并且我没有得到任何警告或错误我编译。
我也真的不想多次复制完全相同的逻辑来处理不同的dict类型。 I.E.,处理[String:Any]
,[String:AnyObject]
和[String:String]
实际上具有完全相同的逻辑。
我见过的唯一可能的解决方案是实际复制字典,这看起来相当昂贵(Convert [String: AnyObject] to [String: Any])。出于性能原因,最好只复制粘贴代码并更改功能签名......但实际上!这似乎太过分了。
最佳解决方案似乎是将Dict解析为[String:AnyObject]
并复制值仅如果它是[String:Any]
:
if let dict = object as? [String:Any] {
var objDict: [String:AnyObject] = [:]
for (key, value) in dict {
if let obj = value as? AnyObject {
objDict[key] = obj
}
}
return self.parseDict(objDict)
我不是特别喜欢这个,但到目前为止,我能够想出最好的。
有没有人知道如何正确处理这个问题?我特别担心我可以将Any
转换为[String:AnyObject]
,将其传递给一个带[String:Any]
的函数,并且我没有编译错误,即使它在运行时崩溃。