如何在解码 JSON 内容时 set/copy 构造 属性
How to set/copy Struct property while decoding JSON content
我有一个结构来解码 json 内容:
struct CustomResponse: Decodable {
var network: String
var weight: Int = 0
var pureWeight: Int
enum CodingKeys: String, CodingKey {
case network = "network"
case weight = "weight"
}}
我想设置从 JSON 解析到 pureWeight
属性 的初始 weight
值。即使后面改了weight
,pureWeight
也应该是JSON响应过来的pureWeight
。
有什么简单的方法可以设置 pureWeight
一次(解析后)而不使用手动解码所有 json 内容?
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
...parsing all items one by one.
}
我使用了这段代码,但显然它总是返回重量的变异值:
var pureWeight: Int {
get {
return weight
}
}
你可以像下面这样处理
保持 init
:
import Foundation
let json = """
{
"network" : "My Awesome network",
"weight" : 100
}
"""
struct CustomResponse: Decodable {
var network: String
var pureWeight: Int
// Computed
var weight: Int {
get {
return hiddenWeight ?? pureWeight
}
set {
hiddenWeight = newValue
}
}
// Hidden from the outside world
private var hiddenWeight: Int?
enum CodingKeys: String, CodingKey {
case network
case weight
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
network = try container.decode(String.self, forKey: .network)
pureWeight = try container.decode(Int.self, forKey: .weight)
}
}
let jsonDecoder = JSONDecoder()
if let data = json.data(using: .utf8),
var response = try? jsonDecoder.decode(CustomResponse.self, from: data) {
print(response)
response.weight = 200
print(response)
}
所以这里要做的是,维护一个私有的属性,对外界隐藏。最初它被设置为 nil
。从 JSON 解析时,它是 nil
.
在获取 weight
属性 时我们隐藏 属性 hiddenWeight
或 weight
以防 hiddenWeight
为零。
当 weight
设置为某项时,则设置 hiddenWeight
。
因此从下一次开始,每当请求 weight
时,都会返回 hiddenWeight
。
不使用 init
:
如果要省略 init
实现,则必须使用除 weight
之外的任何其他 属性 名称。我正在使用 myWeight
.
import Foundation
let json = """
{
"network" : "My Awesome network",
"weight" : 100
}
"""
struct CustomResponse: Decodable {
var network: String
var weight: Int
// Computed
var myWeight: Int {
get {
return hiddenWeight ?? weight
}
set {
hiddenWeight = newValue
}
}
// Hidden from the outside world
private var hiddenWeight: Int?
}
let jsonDecoder = JSONDecoder()
if let data = json.data(using: .utf8),
var response = try? jsonDecoder.decode(CustomResponse.self, from: data) {
print(response)
response.myWeight = 200
print(response)
}
您仍然需要自定义 init
,但最简单的方法是 let
声明初始权重 属性,因为它不应更改并将其设置在 init
struct CustomResponse: Decodable {
var network: String
var weight: Int
let pureWeight: Int
enum CodingKeys: String, CodingKey {
case network = "network"
case weight = "weight"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
network = try container.decode(String.self, forKey: .network)
weight = try container.decode(Int.self, forKey: .weight)
pureWeight = weight
}
}
我有一个结构来解码 json 内容:
struct CustomResponse: Decodable {
var network: String
var weight: Int = 0
var pureWeight: Int
enum CodingKeys: String, CodingKey {
case network = "network"
case weight = "weight"
}}
我想设置从 JSON 解析到 pureWeight
属性 的初始 weight
值。即使后面改了weight
,pureWeight
也应该是JSON响应过来的pureWeight
。
有什么简单的方法可以设置 pureWeight
一次(解析后)而不使用手动解码所有 json 内容?
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
...parsing all items one by one.
}
我使用了这段代码,但显然它总是返回重量的变异值:
var pureWeight: Int {
get {
return weight
}
}
你可以像下面这样处理
保持 init
:
import Foundation
let json = """
{
"network" : "My Awesome network",
"weight" : 100
}
"""
struct CustomResponse: Decodable {
var network: String
var pureWeight: Int
// Computed
var weight: Int {
get {
return hiddenWeight ?? pureWeight
}
set {
hiddenWeight = newValue
}
}
// Hidden from the outside world
private var hiddenWeight: Int?
enum CodingKeys: String, CodingKey {
case network
case weight
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
network = try container.decode(String.self, forKey: .network)
pureWeight = try container.decode(Int.self, forKey: .weight)
}
}
let jsonDecoder = JSONDecoder()
if let data = json.data(using: .utf8),
var response = try? jsonDecoder.decode(CustomResponse.self, from: data) {
print(response)
response.weight = 200
print(response)
}
所以这里要做的是,维护一个私有的属性,对外界隐藏。最初它被设置为 nil
。从 JSON 解析时,它是 nil
.
在获取 weight
属性 时我们隐藏 属性 hiddenWeight
或 weight
以防 hiddenWeight
为零。
当 weight
设置为某项时,则设置 hiddenWeight
。
因此从下一次开始,每当请求 weight
时,都会返回 hiddenWeight
。
不使用 init
:
如果要省略 init
实现,则必须使用除 weight
之外的任何其他 属性 名称。我正在使用 myWeight
.
import Foundation
let json = """
{
"network" : "My Awesome network",
"weight" : 100
}
"""
struct CustomResponse: Decodable {
var network: String
var weight: Int
// Computed
var myWeight: Int {
get {
return hiddenWeight ?? weight
}
set {
hiddenWeight = newValue
}
}
// Hidden from the outside world
private var hiddenWeight: Int?
}
let jsonDecoder = JSONDecoder()
if let data = json.data(using: .utf8),
var response = try? jsonDecoder.decode(CustomResponse.self, from: data) {
print(response)
response.myWeight = 200
print(response)
}
您仍然需要自定义 init
,但最简单的方法是 let
声明初始权重 属性,因为它不应更改并将其设置在 init
struct CustomResponse: Decodable {
var network: String
var weight: Int
let pureWeight: Int
enum CodingKeys: String, CodingKey {
case network = "network"
case weight = "weight"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
network = try container.decode(String.self, forKey: .network)
weight = try container.decode(Int.self, forKey: .weight)
pureWeight = weight
}
}