【发布时间】:2020-07-19 21:40:09
【问题描述】:
我想要类对象JSONSerialization。所以我的输入是[String: Any],从文档中我知道它可能是NSNull、NSString 或NSNumber。所以我制定了一个协议:
protocol PlainValue { }
以上都符合这个协议:
extension NSString: PlainValue { }
extension NSNull: PlainValue { }
extension NSNumber: PlainValue { }
然后我想创建一个保存键值的类存储,例如:
class KeyValue<T: PlainValue> {
let key: NSString
let value: T
init(key: NSString, value: T) {
self.key = key
self.value = value
}
}
并且想这样使用它:
func parse(json: [String: Any]) {
...
if let value = json[key] as? PlainValue { // this should be `Any` but I want to check here if thats an PlainValue or embedded object
let obj = KeyValue<PlainValue>(key: key, value: value) // this currently not working
...
}
...
}
但我的问题是如何在协议级别声明此对象创建。如果我这样做:
protocol PlainValue {
func convert(key: NSString) -> KeyValue<PlainValue>
}
我收到错误:
协议类型“PlainValue”的值不能符合“PlainValue”;只有结构/枚举/类类型可以符合协议
有道理,因为我已经在协议声明中。所以我有一种感觉,也许这应该在KeyValue<T> 级别上声明?但我不确定我是否走在正确的道路上,因为我在尝试采用的每一种方法上都会遇到编译器错误。谁能指出我正确的方向如何使它工作?
我觉得最接近工作的方法是:
extension NSNumber: PlainValue {
func convert(key: NSString) -> KeyValue<NSNumber> {
return KeyValue<NSNumber>(key: key, value: self)
}
}
在NSString 和NSNull 上与上述类似,但不确定如何在协议级别声明它以使其可以从我的解析函数中调用。自从
protocol PlainValue: JSONValue {
func convert(key: NSString) -> KeyValue<Self> // this claims that implementation does not match this declaration
func convert<T: PlainValue>(key: NSString) -> KeyValue<T> // same as above
associatedtype Object: PlainValue
func convert(key: NSString) -> KeyValue<Object> // this is working! But... then I cannot check if value is PlainValue in my parsing function, because of `Protocol 'PlainValue' can only be used as a generic constraint because it has Self or associated type requirements`
}
【问题讨论】: