在Swift 2中用自定义消息抛出错误/exception的最简单方法是什么?
我想在Swift 2中做一些我习惯于用其他语言来做的事情:用自定义消息抛出一个运行时exception。 例如(在Java中):
throw new RuntimeException("A custom message here")
我明白,我可以抛出符合ErrorType协议的枚举types,但我不想为每个types的错误定义枚举。 理想情况下,我希望能够尽可能地模仿上面的例子。 我研究了创build一个实现ErrorType协议的自定义类,但我甚至不知道该协议需要什么(请参阅文档 )。 想法?
最简单的方法可能是定义一个自定义enum
与一个附加了一个String
情况:
enum MyError : ErrorType { case RuntimeError(String) }
用法如下所示:
func throwError(message: String) throws { throw MyError.RuntimeError(message) } do { try throwError("foo") } catch MyError.RuntimeError(let errorMessage) { print(errorMessage) }
如果你想使用现有的types,最通用的将是一个NSError
,你可以做一个工厂方法来创build和抛出一个自定义消息。
最简单的方法是使String
符合Error
:
extension String: Error {}
然后你可以抛出一个string:
throw "Some Error"
要使string本身成为错误的localizedString
,您可以扩展LocalizedError
:
extension String: LocalizedError { public var errorDescription: String? { return self } }
检查这个很酷的版本。 这个想法是实现String和ErrorType协议,并使用错误的rawValue。
enum UserValidationError: String, ErrorType { case NoFirstNameProvided = "Please insert your first name." case NoLastNameProvided = "Please insert your last name." case NoAgeProvided = "Please insert your age." case NoEmailProvided = "Please insert your email." }
用法:
do { try User.define(firstName, lastName: lastName, age: age, email: email, gender: gender, location: location, phone: phone) } catch let error as User.UserValidationError { print(error.rawValue) return }
@ nick-keets的解决scheme是最优雅的,但它在testing目标中遇到了下面的编译时错误:
Redundant conformance of 'String' to protocol 'Error'
这是另一种方法:
struct RuntimeError: Error { let message: String init(_ message: String) { self.message = message } public var localizedDescription: String { return message } }
并使用:
throw RuntimeError("Error message.")
基于@Nick keets的回答,这里有一个比较完整的例子:
extension String: Error {}/*Enables you to throw a string*/ extension String: LocalizedError {/*Adds error.localizedDescription to Error instances*/ public var errorDescription: String? { return self } } func test(color:NSColor) throws{ if color == .red { throw "I don't like red" }else if color == .green { throw "I'm not into green" }else { throw "I like all other colors" } } do { try test(color:.green) } catch let error where error.localizedDescription == "I don't like red"{ Swift.print ("Error: \(error)")//"I don't like red" }catch let error { Swift.print ("Other cases: Error: \(error.localizedDescription)")/*I like all other colors*/ }
最初发表在我的swift博客上: http : //eon.codes/blog/2017/09/01/throwing-simple-errors/
Swift 4:
按照:
https://developer.apple.com/documentation/foundation/nserror
如果你不想定义一个自定义的exception,你可以使用一个标准的NSError对象,如下所示:
import Foundation do { throw NSError(domain: "my error description", code: 42, userInfo: ["ui1":12, "ui2":"val2"] ) } catch let error as NSError { print("Caught NSError: \(error.localizedDescription), \(error.domain), \(error.code)") let uis = error.userInfo print("\tUser info:") for (key,value) in uis { print("\t\tkey=\(key), value=\(value)") } }
打印:
Caught NSError: The operation could not be completed, my error description, 42 User info: key=ui1, value=12 key=ui2, value=val2
这允许你提供一个自定义的string,加上一个数字代码和一个包含你需要的所有额外数据的字典。
注意:这是在OS = Linux(Ubuntu 16.04 LTS)上testing的。