gpt4 book ai didi

swift - 有没有办法更简洁地使用 guard 语句?

转载 作者:搜寻专家 更新时间:2023-11-01 07:13:35 24 4
gpt4 key购买 nike

我正在使用 Gloss对于我的 JSON 实例化。这是一个示例类:

public class MyObj: Decodable
{
let id_user : String
let contact_addr1 : String
let contact_addr2 : String?
let contact_city : String
let contact_state : String
let contact_zip : String
let points : Int

// Deserialization
required public init?(json: JSON)
{
guard let id_user : String = "somekey" <~~ json else {
assertionFailure("MyObj - invalid JSON. Missing key: wouldbenicetonotwritethisforeachmember")
return nil
}
guard let contact_addr1 : String = "somekey" <~~ json else {
assertionFailure("MyObj - invalid JSON. Missing key: wouldbenicetonotwritethisforeachmember")
return nil
}
guard let contact_city : String = "somekey" <~~ json else {
assertionFailure("MyObj - invalid JSON. Missing key: wouldbenicetonotwritethisforeachmember")
return nil
}
guard let contact_state : String = "somekey" <~~ json else {
assertionFailure("MyObj - invalid JSON. Missing key: wouldbenicetonotwritethisforeachmember")
return nil
}
guard let contact_zip : String = "somekey" <~~ json else {
assertionFailure("MyObj - invalid JSON. Missing key: wouldbenicetonotwritethisforeachmember")
return nil
}
guard let points : Int = "somekey" <~~ json else {
assertionFailure("MyObj - invalid JSON. Missing key: wouldbenicetonotwritethisforeachmember")
return nil
}

self.id_user = id_user
self.contact_addr1 = contact_addr1
self.contact_addr2 = "somekey" <~~ json
self.contact_city = contact_city
self.contact_state = contact_state
self.contact_zip = contact_zip
self.contact_points = points
}
}

我有很多模型类。他们之间有数百名成员。为每个人写一个多行保护语句真的让我的代码变得垃圾。有什么办法可以将守卫功能封装成更简洁的东西吗?也许是一个函数或类似的东西:

shortGuard("memberName", "jsonKey")

也许有一种方法可以防止字符串键数组?

最佳答案

有多种方法可以实现这一点。它们都归结为编写一个包装函数来将您的键映射到值。以下是我想到的几个简单示例,但正如我所说,有很多方法可以做到这一点,具体取决于您所追求的目标:

enum JSONError: Error {
case keyNotFound(String)
}

extension JSON {
func values<T>(for keys: [String]) throws -> [T] {
var values = [T]()

for key in keys {
guard let value: T = key <~~ self else {
throw JSONError.keyNotFound(key)
}

values.append(value)
}

return values
}

func values<T>(for keys: [String], closure: ((_ key: String, _ value: T) -> Void)) throws {
for key in keys {
guard let value: T = key <~~ self else {
throw JSONError.keyNotFound(key)
}

closure(key, value)
}
}
}

第一个在您可以使用任何键之前验证所有键,如果不存在则抛出。你会像这样使用它:

do {
let keys = ["foo", "bar"]

// The type of the values constant is important.
// In this example we're saying look for values of type Int.
let values: [Int] = try json.values(for: keys)

for (index, key) in keys.enumerated() {
print("value for \(key): \(values[index])")
}
} catch JSONError.keyNotFound(let key) {
assertionFailure("key not found \(key)")
}

第二个会将出现在您的键数组中的键、值对传回闭包,并将抛出它发现不存在的第一个。

do {
let keys = ["foo", "bar"]

// The type of the closure's value argument is important.
// In this example we're saying look for values of type String.
try json.values(for: keys) { (key, value: String) in
print("value for key \(key) is \(value)")
}
} catch JSONError.keyNotFound(let key) {
assertionFailure("key not found \(key)")
}

在您的类的 init?() 函数中使用第一个版本,我们有这样的东西:

public struct MyObj: Decodable {
public let id_user : String
public let contact_addr1 : String
public let contact_addr2 : String?
public let points : Int

public init?(json: S) {
do {
let stringKeys = ["id_user", "contact_addr1"]
let stringValues: [String] = try json.values(for: stringKeys)

id_user = stringValues[0]
contact_addr1 = stringValues[1]

// this isn't required, so just extract with no error if it fails
contact_addr2 = "contact_addr2" <~~ json

let intKeys = ["points"]
let intValues: [Int] = try json.values(for: intKeys)

points = intValues[0]
} catch JSONError.keyNotFound(let key) {
assertionFailure("key \(key) not found in JSON")
return nil
} catch {
return nil
}
}
}

关于swift - 有没有办法更简洁地使用 guard 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43578910/

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