Swift 中的 JSON 对象

问题描述 投票:0回答:1

出于我的应用程序的目的,我使用定义如下的 JSON 对象:

typealias JSONObject = [String:JSONValue]

其中 JSON Value 是可能的类型符合的协议:

protocol JSONValue {}
extension String:      JSONValue {}
extension Int:         JSONValue {}
extension Double:      JSONValue {}
extension Bool:        JSONValue {}
extension NSNull:      JSONValue {}
extension JSONObject:  JSONValue {}

(我更喜欢使用这种方式,而不是使用 .string(value)、.int(value) 等创建 JSONValue 枚举......我的代码是私有的,没有人会添加其他扩展)

为了处理数组,我添加了:

extension [JSONValue]: JSONValue {}

因此任何 JSONValue 都可以是原始值、数组或字典 (JSONObject)

一切正常。我只是遇到数组问题。看这个例子:

var myObject = JSONObject()
myObject["primitive"] = "OK"
myObject["array"] = ["OK"]

let myObjectAsJSONValue: JSONValue = myObject // OK


var myArray = [JSONObject]()
myArray.append(myObject)

let myArrayAsJSONValue: JSONValue = myArray // Failing (Protocol 'JSONValue' requires the types 'JSONObject' (aka 'Dictionary<String, any JSONValue>') and 'any JSONValue' be equivalent)

我不明白我得到的错误,因为 JSONObject 符合 JSONValue(因此可以作为“任何 JSONValue”处理)

任何帮助??

谢谢!

编辑: 通过替换解决了我的问题:

extension [JSONValue]: JSONValue {}

搭配:

extension Array : JSONValue where Element : JSONValue {}

我不太明白其中的区别,但它似乎有效......

json swift type-erasure
1个回答
0
投票

如编辑所述,您应该像这样编写数组扩展:

extension Array : JSONValue where Element : JSONValue {}

这与

extension [JSONValue] ...
的不同之处在于
extension [JSONValue]
仅在 one 类型上声明扩展 -
Array<any JSONValue>
.

所以如果你只是声明

myArray
为:

var myArray = [any JSONValue]()

不会有错误

您代码中的

myArray
类型为
Array<JSONObject>
。这是与
Array<any JSONValue>
不同的类型,因此
extension [JSONValue]
不适用于它——它不符合
JSONValue

如果扩展是

extension Array : JSONValue where Element : JSONValue
,那么扩展适用于所有
Array
类型,其中
Element
类型符合
JSONValue
。因为
JSONObject
符合
JSONValue
,所以
Array<JSONObject>
也符合。

© www.soinside.com 2019 - 2024. All rights reserved.