gpt4 book ai didi

swift - 如何实现上下文可控的Swift Codable Encode函数?

转载 作者:可可西里 更新时间:2023-11-01 01:07:30 26 4
gpt4 key购买 nike

我正在尝试为 Codable 结构实现一个编码器,我可以通过传入一个上下文来控制它,该上下文确定我将哪些字段添加到输出 JSON 中。但我想不出一个好的方法。

例如假设我有以下内容:

import Foundation

struct MyStruct: Encodable {
var a:Int = 0
var b:Int = 0

enum CodingKeys: String, CodingKey {
case a
case b
}

enum Context {
case summary, full
}

// I can write something like this
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(a, forKey: .a)
try container.encode(b, forKey: .b)
}

// ...but I want to write is something like this
func encode(to encoder: Encoder, withContextcontext: Context ) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(a, forKey: .a)

if context == .full
{
try container.encode(b, forKey: .b)
}
}

}

var myObject = MyStruct()
myObject.a = 10
myObject.b = 5

let jsonEncoder = JSONEncoder()
do {
let jsonData = try jsonEncoder.encode(myObject)
// let jsonData = try jsonEncode.encode(myObject, withContext:.full)
let jsonString = String(data: jsonData, encoding: .utf8)!
print(jsonString)
} catch {
print(error)
}

是否有任何好的解决方案可以提供与我想象的 encode(:WithContext) 功能相同的效果?

我有一个不太热衷的解决方案是将上下文变量添加到结构中并在调用 encode() 之前设置它:

struct MyStruct: Encodable {
var a:Int = 0
var b:Int = 0
var context = .full

enum CodingKeys: String, CodingKey {
case a
case b
}

enum Context {
case summary, full
}



// But I want to write is something like this
func encode(to encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(a, forKey: .a)

if context == .full
{
try container.encode(b, forKey: .b)
}
}

}

var myObject = MyStruct()
myObject.a = 10
myObject.b = 5
myObject.context = .summary

let jsonEncoder = JSONEncoder()
do {
let jsonData = try jsonEncoder.encode(myObject)
let jsonString = String(data: jsonData, encoding: .utf8)!
print(jsonString)
} catch {
print(error)
}

不确定是否要将此 Context 变量添加到我拥有的每个结构中。有没有更优雅的方式?

最佳答案

如果你需要传递一些上下文给Encoder,你总是可以使用Encoder.userInfo :

Any contextual information set by the user for encoding.

例子:

struct MyStruct: Encodable {
var a:Int = 0
var b:Int = 0

enum CodingKeys: String, CodingKey {
case a
case b
}

enum Context {
case summary, full

static let encodingKey = CodingUserInfoKey(rawValue: "my_struct_context")!
}

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(a, forKey: .a)

if (encoder.userInfo[Context.encodingKey] as? Context) == .full {
try container.encode(b, forKey: .b)
}
}
}

var myObject = MyStruct()
myObject.a = 10
myObject.b = 5

let jsonEncoder = JSONEncoder()
jsonEncoder.userInfo = [
MyStruct.Context.encodingKey: MyStruct.Context.summary
]

do {
let jsonData = try jsonEncoder.encode(myObject)
let jsonString = String(data: jsonData, encoding: .utf8)!
print(jsonString)
} catch {
print(error)
}

关于swift - 如何实现上下文可控的Swift Codable Encode函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54853890/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com