記事


throw する式の結果の保存


結果を直列化またはメモ化する必要がある場合は、throw する式を包み込むイニシャライザーを呼び出します。





概観


関数呼び出しや、値を throw したり返したりできるその他の式の結果全体を保存する必要がある場合があります。例えば、結果を直列化したり、結果データを処理するあなたのアプリの別の部分に値として渡したりする必要があります。このようなシナリオでは、Result 型を使用して、失敗する可能性のある操作の結果をキャプチャします。



Throw する式を保存すべきと特定する


通常、do-catch 文は throw する式を即座に処理するために使用しますが、バッチ呼び出しの分析などのタスクでは、後続の処理のために操作結果全体を保存する必要がある場合もあります。以下の例では、乱数を生成するものの、約半分の確率で失敗する 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
        }
    }
}


Throw する式を結果に変換する


Result 列挙型の iinit(catching:) イニシャライザを使用して、throw する式からの戻り値または throw されたエラーを保存して下さい。イニシャライザに渡すクロージャ内で、throw する式を呼び出します。


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

ほとんどのシナリオでは、保存された結果は、あなたのコード内のより広範な機能の一部として使用されます。例えば、一連のランダム性テストを実行し、乱数ジェネレータから返される数値の範囲と、API 呼び出しの失敗率の両方の統計的平均を計算する場合があります。このような場合、成功値や API 呼び出しの失敗だけでなく、結果全体を保存する必要があります。


以下の例では、一連の呼び出しを後で統計分析するために保存するという広いコンテキストで 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)
        )
    }
}

十分に大きなサンプルで分析を実行すると、平均値は 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%."




以下も見よ


Throw する式を結果に変換する


init(catching:)

throw するクロージャを評価し、返された値を成功としてキャプチャするか、throw されたエラーを失敗としてキャプチャすることにより、新しい結果を作成します。














トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ












トップへ