问题描述
为什么数组名称不能解码?
Why is the names Array not decoding?
为操场做准备,简单地将其粘贴到操场上
Prepared for Playground, Simple paste this into your playground
import Foundation
struct Country : Decodable {
enum CodingKeys : String, CodingKey {
case names
}
var names : [String]?
}
extension Country {
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
names = try values.decode([String]?.self, forKey: .names)!
}
}
let json = """
[{
"names":
[
"Andorre",
"Andorra",
"アンドラ"
]
},{
"names":
[
"United Arab Emirates",
"Vereinigte Arabische Emirate",
"Émirats Arabes Unis",
"Emiratos Árabes Unidos",
"アラブ首長国連邦",
"Verenigde Arabische Emiraten"
]
}]
""".data(using: .utf8)!
let decoder = JSONDecoder()
do {
let countries = try decoder.decode([Country].self, from: json)
countries.forEach { print($0) }
} catch {
print("error")
}
推荐答案
您已将名称
定义为可选属性>国家。
如果您的意图是该密钥可能不存在于JSON
中,请使用 decodeIfPresent
:
You have defined names
as an optional property of Country
.If your intention is that this key may not be present in the JSONthen use decodeIfPresent
:
extension Country {
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
names = try values.decodeIfPresent([String].self, forKey: .names)
}
}
如果容器没有与键相关联的值,或者该值为null,则此方法返回 nil
。
This method returns nil
if the container does not have a value associated with key, or if the value is null.
但是实际上您可以省略自定义的 init(来自解码器:解码器)
实现(以及枚举CodingKeys
),因为这是默认行为,将自动合成
。
But actually you can just omit your custom init(from decoder: Decoder)
implementation (and the enum CodingKeys
), because that is the default behaviour and willbe synthesized automatically.
备注:在任何 catch
子句中都定义了一个隐式变量 error
,所以
是这样
Remark: An implicit variable error
is defined in any catch
clause,so
} catch {
print(error.localizedDescription)
}
可能比 print( error)更具信息性
(尽管在这种情况下不是
)。
can be more informative than just a print("error")
(although notin this particular case).
这篇关于可编码/可解码应使用字符串解码数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!