Article

Preserving the Results of a Throwing Expression スローする式の結果を保全する

Call the initializer that wraps a throwing expression when you need to serialize or memoize the result. スローする式をラップするイニシャライザを呼び出します、あなたが結果をシリアライズまたは記憶する必要がある時に。

Overview 概要

Sometimes you need to preserve the entire result of a function call or other expression that can either throw or return a value. For example, you may need to serialize the result or pass it as a value to another part of your app that handles the result data. Use the Result type in these scenarios to capture the result of a potentially failing operation. 時々あなたはスローするまたは値を返すどちらかが可能な関数呼び出しや他の式の結果の全体を保全する必要があります。例えば、あなたは結果をシリアライズするまたはそれをある値としてあなたのアプリの別の部分に、結果データを処理するものに渡す必要があるかもしれません。Result型をそれらの状況において使用して、失敗する可能性のある演算の結果をキャプチャしてください。

Identify a Throwing Expression to Preserve スローする式を識別することで保全する

Typically, you use do-catch statements to handle throwing expressions immediately, but sometimes you need to store the whole result of the operation for later processing during tasks like analyzing a batch of calls. The following example introduces an API that generates random numbers, but that fails approximately half of the time. 概して、あなたはdo-catch文を使うことでスロー式を直接に取り扱います、しかし時にはあなたは演算の結果全体を保管しておく必要があります、もっと後で、一群の呼び出しを分析することのような作業の間に処理するために。以下の例は、無作為な数を生成するあるAPIを導入します、しかしそれはおおよそ半分は失敗します。


enum EntropyError: Error {
    case entropyDepleted
}


struct UnreliableRandomGenerator {
    func random() throws -> Int {
        if Bool.random() {
            return Int.random(in: 1...100)
        } else {
            throw EntropyError.entropyDepleted
        }
    }
}

Convert the Throwing Expression to a Result スローする式を結果へと変換する

You preserve the return value or thrown error from a throwing expression using the Result enumeration’s init(catching:) initializer. Invoke the throwing expression inside the closure you pass to the initializer: あなたはスローする式から戻り値またはスローされたエラーを、Result列挙の持つinit(catching:)イニシャライザを使って保全します。スロー式をあなたがこのイニシャライザに渡すクロージャ内から発動してください。


let singleSample = Result { try UnreliableRandomGenerator().random() }

In most scenarios, you use the preserved result as part of broader functionality in your code. For example, you may run a series of randomness tests and compute the statistical average of both a range of numbers returned from a random number generator, as well as the failure rate of calling the API. In these cases, you need to store the whole result rather than just the success value or that the API call failed. ほとんどの状況では、あなたは保全された結果をあなたのコードにおけるより幅広い機能性の一部として使います。例えば、あなたは一連の無作為性テストを走らせて、無作為数生成子から返されたある範囲の数、それだけでなくそのAPI呼び出しの失敗割合の両方の統計上の平均を計算するかもしれません。これらの場合において、あなたは全体の結果を取っておく必要があります、成功値またはAPI呼び出しが失敗したことだけでなく。

The following example uses the init(catching:) initializer in the broader context of saving a series of calls for later statistical analysis: 以下の例は、init(catching:)イニシャライザを、後で統計学的に分析するために一連の呼び出しを保存する、より幅広い文脈において使います:


struct RandomnessMonitor {
    let randomnessSource: UnreliableRandomGenerator
    var results: [Result<Int, Error>] = []
    
    init(generator: UnreliableRandomGenerator) {
        randomnessSource = generator
    }
    
    mutating func sample() {
        let sample = Result { try randomnessSource.random() }
        results.append(sample)
    }
    
    func summary() -> (Double, Double) {
        let totals = results.reduce((sum: 0, count: 0)) { total, sample in
            switch sample {
            case .success(let number):
                return (total.sum + number, total.count)
            case .failure:
                return (total.sum, total.count + 1)
            }
        }
        
        return (
            average: Double(totals.sum) / Double(results.count - totals.count),
            failureRate: Double(totals.count) / Double(results.count)
        )
    }
}

Running the analysis on a sufficiently large sample generates an average number near 50 and a failure rate near 50%: 十分に大きなサンプル上での分析の実行は、50に近い平均数と50%に近い失敗割合を生成します:


var monitor = RandomnessMonitor(generator: UnreliableRandomGenerator())
(0..<1000).forEach { _ in monitor.sample() }
let (average, failureRate) = monitor.summary()
print("Average value: \(average), failure rate: \(failureRate * 100.0)%.")
// Prints values such as: "Average value: 47.95, failure rate: 48.69%."

See Also 参照

Converting a Throwing Expression to a Result スローする式を結果へ変換する