Swift - 使用协议定义递归类型

时间:2015-09-09 09:08:33

标签: json swift nsjsonserialization

我想定义一个可以序列化为有效JSON对象的类型

因此,例如,如果JSON可以包含以下内容:

String 
Number 
Array 
Object
Date
Boolean

我想定义一个有效类型的协议

protocol JsonSerializable {
}

typealias JSONObject = [String : JsonSerializable]
typealias JSONArray = [JsonSerializable]

// foundation implements serializing numbers + strings + dates etc. to JSON
extension String : JsonSerializable {}
extension Int : JsonSerializable {}

// problem with defining dictionary and array of JSON-able types
extension Dictionary : JsonSerializable {}
...

问题是如何确保字典只包含可序列化的类型(在编译时)

2 个答案:

答案 0 :(得分:3)

首先,我建议你阅读Empowering Extensions in Swift 2: Protocols, Types and Subclasses (Xcode 7 beta 2)。 (因为它是针对beta 2进行了一些小改动)

回到你的问题。对于Array

extension Array where Element: JsonSerializable {
    var json: String { ... }
}

[1, 2, 3].json     // Valid
[true, false].json // Invalid; `Bool` doesn't conform to `JsonSerializable`.

字典有点棘手,因为如上所述:

  

以这种方式扩展泛型类型的当前规则是   在where关键字必须是类或a之后引用的类型   协议

因此,您无法指定Key的{​​{1}}必须是Dictionary。本文中给出的解决方法是定义String协议:

StringType

现在为字典扩展:

protocol StringType {
    var characters: String.CharacterView { get }
}
extension String: StringType {}

或者,您可以创建自己的extension Dictionary where Key: StringType, Value: JsonSerializable { var json: String { ... } } ["A": 1, "B": 2].json // Valid [1: "1", 2: "2"].json // Invalid; `Int` doesn't conform to `StringType`. ["A": true, "B": false].json // Invalid; `Bool` doesn't conform to `JsonSerializable`. JsonArray类型,这些类型将分别由JsonDictionaryArray支持:

Dictionary

答案 1 :(得分:1)

据我所知,今天在Xcode 7 beta 6中是不可能的。

如果您需要,可以复制此雷达:http://openradar.appspot.com/radar?id=5623386654900224