Swift: 错误忽略 try 语句
Swift: Error ignores try statement
在我的代码中,我使用 SWXMLHash 库反序列化了一些 XML。它的 .value()
方法在其声明中有 throws
关键字,任何自定义反序列化函数也是如此。
我有下面一行代码:
let myValue : UInt8 = try? xml["Root"]["ValueNode"].value()
由于库不包含 UInt8
的反序列化器,我定义了自己的反序列化器:
extension UInt8: XMLElementDeserializable {
public static func deserialize(_ element: XMLElement) throws -> UInt8 {
return UInt8(element.text)!
}
}
这在节点有值时有效。但是,当节点不存在或为 nil 时,会在以下行发生错误:
return UInt8(element.text)! // Fatal error: Unexpectedly found nil while unwrapping an Optional value
这显然是应该发生的。我不明白的是为什么这个错误没有被我的 try?
语句捕获并返回 nil
而不是抛出那个错误。
有人能帮忙吗?
return UInt8(element.text)!
这一行没有try
。因此,这里不会抛出任何错误。如果 UInt8
不能转换给定的字符串,它只是 returns nil
。然后,当然,您的 !
将 nil
变成了崩溃。
相反,做这样的事情:
guard let retVal = UInt8(element.text) else { throw SomeError }
return retVal
总的来说:如果有一种方法可以使用 !
来做某事,而另一种方法可以不使用 !
来做同样的事情,那就选择第二种,除非你真的有很好的理由。
并非所有错误都可以在Swift中捕获。如果您使用 throws
关键字标记函数,则表示该函数可能会抛出 可恢复 错误。但是,您的自定义实现实际上不会引发任何错误。只有用 throws
关键字标记的函数抛出的错误和使用代码 throw Error
抛出的错误才能被 do-catch 块捕获。
try?
是一种将可抛出函数的 return 值转换为可选值的方法。如果函数会抛出错误,try?
之后的值将是 nil
,否则它将是一个可选值。
当你使用 !
时,你明确地告诉编译器你知道你在做什么,如果你使用 !
的操作失败,你的应用程序不应该优雅地失败.
您需要更改 deserialize
方法以优雅地处理可选的解包或抛出错误。
extension UInt8: XMLElementDeserializable {
public static func deserialize(_ element: XMLElement) throws -> UInt8 {
if let val = UInt8(element.text) {
return val
} else {
throw NSError(domain: "Couldn't deserialize value to UInt8", code: 1)
}
}
}
在我的代码中,我使用 SWXMLHash 库反序列化了一些 XML。它的 .value()
方法在其声明中有 throws
关键字,任何自定义反序列化函数也是如此。
我有下面一行代码:
let myValue : UInt8 = try? xml["Root"]["ValueNode"].value()
由于库不包含 UInt8
的反序列化器,我定义了自己的反序列化器:
extension UInt8: XMLElementDeserializable {
public static func deserialize(_ element: XMLElement) throws -> UInt8 {
return UInt8(element.text)!
}
}
这在节点有值时有效。但是,当节点不存在或为 nil 时,会在以下行发生错误:
return UInt8(element.text)! // Fatal error: Unexpectedly found nil while unwrapping an Optional value
这显然是应该发生的。我不明白的是为什么这个错误没有被我的 try?
语句捕获并返回 nil
而不是抛出那个错误。
有人能帮忙吗?
return UInt8(element.text)!
这一行没有try
。因此,这里不会抛出任何错误。如果 UInt8
不能转换给定的字符串,它只是 returns nil
。然后,当然,您的 !
将 nil
变成了崩溃。
相反,做这样的事情:
guard let retVal = UInt8(element.text) else { throw SomeError }
return retVal
总的来说:如果有一种方法可以使用 !
来做某事,而另一种方法可以不使用 !
来做同样的事情,那就选择第二种,除非你真的有很好的理由。
并非所有错误都可以在Swift中捕获。如果您使用 throws
关键字标记函数,则表示该函数可能会抛出 可恢复 错误。但是,您的自定义实现实际上不会引发任何错误。只有用 throws
关键字标记的函数抛出的错误和使用代码 throw Error
抛出的错误才能被 do-catch 块捕获。
try?
是一种将可抛出函数的 return 值转换为可选值的方法。如果函数会抛出错误,try?
之后的值将是 nil
,否则它将是一个可选值。
当你使用 !
时,你明确地告诉编译器你知道你在做什么,如果你使用 !
的操作失败,你的应用程序不应该优雅地失败.
您需要更改 deserialize
方法以优雅地处理可选的解包或抛出错误。
extension UInt8: XMLElementDeserializable {
public static func deserialize(_ element: XMLElement) throws -> UInt8 {
if let val = UInt8(element.text) {
return val
} else {
throw NSError(domain: "Couldn't deserialize value to UInt8", code: 1)
}
}
}