Swift Language
エラー処理
サーチ…
備考
エラーの詳細については、Swiftプログラミング言語を参照してください。
エラー処理の基本
Swiftの関数は、値を返したり、 エラーを投げたり、あるいはその両方を返します。
func reticulateSplines() // no return value and no error
func reticulateSplines() -> Int // always returns a value
func reticulateSplines() throws // no return value, but may throw an error
func reticulateSplines() throws -> Int // may either return a value or throw an error
ErrorTypeプロトコル (NSErrorオブジェクトを含む)に準拠する値は、エラーとしてスローされる可能性があります。 列挙は、カスタムエラーを定義する便利な方法を提供します。
enum NetworkError: ErrorType {
case Offline
case ServerError(String)
}
enum NetworkError: Error {
// Swift 3 dictates that enum cases should be `lowerCamelCase`
case offline
case serverError(String)
}
エラーは、プログラムの実行中に致命的ではない障害を示し、特殊な制御フロー構造do
/ catch
、 throw
、 try
ます。
func fetchResource(resource: NSURL) throws -> String {
if let (statusCode, responseString) = /* ...from elsewhere...*/ {
if case 500..<600 = statusCode {
throw NetworkError.serverError(responseString)
} else {
return responseString
}
} else {
throw NetworkError.offline
}
}
do
/ catch
でエラーを捕らえることができます:
do {
let response = try fetchResource(resURL)
// If fetchResource() didn't throw an error, execution continues here:
print("Got response: \(response)")
...
} catch {
// If an error is thrown, we can handle it here.
print("Whoops, couldn't fetch resource: \(error)")
}
try
を使ってエラーを投げる可能性のある関数を呼び出す必要がありますtry?
、またはtry!
:
// error: call can throw but is not marked with 'try'
let response = fetchResource(resURL)
// "try" works within do/catch, or within another throwing function:
do {
let response = try fetchResource(resURL)
} catch {
// Handle the error
}
func foo() throws {
// If an error is thrown, continue passing it up to the caller.
let response = try fetchResource(resURL)
}
// "try?" wraps the function's return value in an Optional (nil if an error was thrown).
if let response = try? fetchResource(resURL) {
// no error was thrown
}
// "try!" crashes the program at runtime if an error occurs.
let response = try! fetchResource(resURL)
異なるエラータイプをキャッチする
この例では独自のエラータイプを作成しましょう。
enum CustomError: ErrorType {
case SomeError
case AnotherError
}
func throwing() throws {
throw CustomError.SomeError
}
enum CustomError: Error {
case someError
case anotherError
}
func throwing() throws {
throw CustomError.someError
}
Do-Catch構文は、スローされたエラーをキャッチすることを可能にし、 catch
ブロックで利用可能なerror
という名前の定数を自動的に作成します。
do {
try throwing()
} catch {
print(error)
}
自分で変数を宣言することもできます:
do {
try throwing()
} catch let oops {
print(oops)
}
また、異なるcatch
文を連鎖させることもできます。これは、Doブロックにいくつかのタイプのエラーがスローされる場合に便利です。
ここでDo-Catchは最初にCustomError
としてエラーをキャストしようとしますが、カスタムタイプが一致しなかった場合はNSError
としてキャストしようとします。
do {
try somethingMayThrow()
} catch let custom as CustomError {
print(custom)
} catch let error as NSError {
print(error)
}
Swift 3では、NSErrorに明示的にダウンキャストする必要はありません。
do {
try somethingMayThrow()
} catch let custom as CustomError {
print(custom)
} catch {
print(error)
}
明示的なエラー処理のためのキャッチとスイッチパターン
class Plane {
enum Emergency: ErrorType {
case NoFuel
case EngineFailure(reason: String)
case DamagedWing
}
var fuelInKilograms: Int
//... init and other methods not shown
func fly() throws {
// ...
if fuelInKilograms <= 0 {
// uh oh...
throw Emergency.NoFuel
}
}
}
クライアントクラス:
let airforceOne = Plane()
do {
try airforceOne.fly()
} catch let emergency as Plane.Emergency {
switch emergency {
case .NoFuel:
// call nearest airport for emergency landing
case .EngineFailure(let reason):
print(reason) // let the mechanic know the reason
case .DamagedWing:
// Assess the damage and determine if the president can make it
}
}
エラー伝播を無効にする
Swiftのクリエイターは、表現力豊かな表現に多くの関心を寄せています。エラー処理は、表現力豊かなものです。エラーをスローする関数を呼び出そうとすると、関数呼び出しの前にtryキーワードが必要です。 tryキーワードは魔法ではありません。それは、開発者が関数の投げ込み能力を認識できるようにすることです。
たとえば、次のコードでは、指定されたパスでイメージリソースをロードするloadImage(atPath :)関数を使用します。イメージをロードできない場合はエラーをスローします。この場合、イメージはアプリケーションと共に出荷されるため、実行時にエラーはスローされないため、エラー伝播を無効にすることが適切です。
let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")
ローカライズされた説明でカスタムエラーを作成する
enum
のカスタムエラーを作成する
enum RegistrationError: Error {
case invalidEmail
case invalidPassword
case invalidPhoneNumber
}
ローカライズされた説明を処理するためのRegistrationError
extension
を作成します。
extension RegistrationError: LocalizedError {
public var errorDescription: String? {
switch self {
case .invalidEmail:
return NSLocalizedString("Description of invalid email address", comment: "Invalid Email")
case .invalidPassword:
return NSLocalizedString("Description of invalid password", comment: "Invalid Password")
case .invalidPhoneNumber:
return NSLocalizedString("Description of invalid phoneNumber", comment: "Invalid Phone Number")
}
}
}
ハンドルエラー:
let error: Error = RegistrationError.invalidEmail
print(error.localizedDescription)