在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的。