如何从 Codable 结构中捕获 init(来自解码器:解码器)中的错误?
Posted
技术标签:
【中文标题】如何从 Codable 结构中捕获 init(来自解码器:解码器)中的错误?【英文标题】:How to do-catch error in init(from decoder:Decoder) from a Codable struct? 【发布时间】:2018-05-18 04:36:17 【问题描述】:let jsonString = """
"name":1,
"gender":"male",
"""
struct Person: Codable
var name: String
var gender: String
public init(from decoder: Decoder) throws
do
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
gender = try container.decode(String.self, forKey: .gender)
catch
print("XXXXXX \(error)")
从上面的代码来看,它不会编译,因为它会报错,
从初始化程序返回而不初始化所有存储的属性。
我想抛出一些错误,但是如果没有,我该怎么做,
-
为每个属性设置默认值。
将它们全部设为可选。
【问题讨论】:
请注意,对于此数据结构,自定义初始化程序是多余的。 【参考方案1】:您不需要init(from decoder: Decoder)
中的do-catch
,因为它已经标记为throws
。所以就这样做吧:
public init(from decoder: Decoder) throws
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
gender = try container.decode(String.self, forKey: .gender)
解码可以使用do-catch
来查看上述init(from:)
方法中抛出的任何异常,如下例所示:
struct Person: Codable
var name: String
var gender: String
// Note: This is not a very good example because this init method
// is not even necessary in this case, since the automatically-
// synthesized `init(from:)` method does exactly the same thing. I've
// left it here to illustrate that you don't need to have a `do-catch`
// in this method and can instead just use `try`, since the method
// is marked as `throws`.
public init(from decoder: Decoder) throws
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
gender = try container.decode(String.self, forKey: .gender)
class PersonDecoder
func person(decodedFrom data: Data) -> Person?
do
// The `JSONDecoder.decode(_:from:)` method calls
// `Person.init(from:)`, which can throw, which is why
// `JSONDecoder.decode(_:from:)` also throws.
let person = try JSONDecoder().decode(Person.self, from: data)
return person
catch
// Inspect any thrown errors here.
print(error)
return nil
let personData = Data("""
"name": 1,
"gender": "male"
""".utf8)
let personDecoder = PersonDecoder()
// Prints: "The data couldn’t be read because it isn’t in the correct format."
// and `person` is nil.
let person = personDecoder.person(decodedFrom: personData)
【讨论】:
那么如何知道异常呢? @Nuibb 如果您在调用周围使用do-catch
来解码数据,则无论解码是什么都可以被告知异常。我将在我的答案中添加一个示例。
@TylerTheCompiler 它没有去捕捉范围。
@TylerTheCompiler 好的,它确实成功了。但是需要编辑 Swift Error 断点才能继续,而不是卡在那里。
@hasan 我不确定你在说什么。以上是关于如何从 Codable 结构中捕获 init(来自解码器:解码器)中的错误?的主要内容,如果未能解决你的问题,请参考以下文章
CoreData 和 Codable 类编译器错误:在从初始化程序返回之前,未在所有路径上调用“self.init”