@@ -101,8 +101,8 @@ Rustでは戻り値を使います。
101
101
<!-- a computation was successful or not. As you will see, the key to ergonomic error -->
102
102
<!-- handling is reducing the amount of explicit case analysis the programmer has to -->
103
103
<!-- do while keeping code composable. -->
104
- エラーハンドリングとは、ある処理が成功したかどうかを * ケース分析 * に基づいて判断するものだと考えられます。
105
- これから見ていくように、エラーハンドリングをエルゴノミックにするために重要なのは、プログラマがコードを合成可能(composable) に保ったまま、明示的なケース分析の回数を 、いかに減らしていくかということです。
104
+ エラーハンドリングとは、ある処理が成功したかどうかを * 場合分け(case analysis) * に基づいて判断するものだと考えられます。
105
+ これから見ていくように、エラーハンドリングをエルゴノミックにするために重要なのは、プログラマがコードを合成可能(composable) に保ったまま、明示的な場合分けの回数を 、いかに減らしていくかということです。
106
106
107
107
<!-- Keeping code composable is important, because without that requirement, we -->
108
108
<!-- could [`panic`](../std/macro.panic!.html) whenever we -->
@@ -280,16 +280,16 @@ fn main() {
280
280
<!-- analysis is the only way to get at the value stored inside an `Option<T>`. This -->
281
281
<!-- means that you, as the programmer, must handle the case when an `Option<T>` is -->
282
282
<!-- `None` instead of `Some(t)`. -->
283
- このコードは ` find ` 関数が返した ` Option<usize> ` の * ケース分析 * に、 [ パターンマッチ] [ 1 ] を使っています。
284
- 実のところ、ケース分析が 、` Option<T> ` に格納された値を取り出すための唯一の方法なのです。
283
+ このコードは ` find ` 関数が返した ` Option<usize> ` の * 場合分け * に、 [ パターンマッチ] [ 1 ] を使っています。
284
+ 実のところ、場合分けが 、` Option<T> ` に格納された値を取り出すための唯一の方法なのです。
285
285
これは、` Option<T> ` が ` Some(t) ` ではなく ` None ` だった時、プログラマであるあなたが、このケースに対処しなければならないことを意味します。
286
286
287
287
<!-- But wait, what about `unwrap`,which we used [`previously`](#code-unwrap-double)? -->
288
288
<!-- There was no case analysis there! Instead, the case analysis was put inside the -->
289
289
<!-- `unwrap` method for you. You could define it yourself if you want: -->
290
290
でも、ちょっと待ってください。 [ さっき] ( #code-unwrap-double ) 使った ` unwrap ` はどうだったでしょうか?
291
- ケース分析はどこにもありませんでした !
292
- 実はケース分析は ` unwrap ` メソッドの中に埋め込まれていたのです。
291
+ 場合分けはどこにもありませんでした !
292
+ 実は場合分けは ` unwrap ` メソッドの中に埋め込まれていたのです。
293
293
もし望むなら、このように自分で定義することもできます:
294
294
295
295
<span id =" code-option-def-unwrap " ></span >
@@ -319,7 +319,7 @@ impl<T> Option<T> {
319
319
<!-- The `unwrap` method *abstracts away the case analysis*. This is precisely the thing -->
320
320
<!-- that makes `unwrap` ergonomic to use. Unfortunately, that `panic!` means that -->
321
321
<!-- `unwrap` is not composable: it is the bull in the china shop. -->
322
- ` unwrap ` メソッドは * ケース分析を抽象化します * 。このことは確かに ` unwrap ` をエルゴノミックにしています。
322
+ ` unwrap ` メソッドは * 場合分けを抽象化します * 。このことは確かに ` unwrap ` をエルゴノミックにしています。
323
323
しかし残念なことに、そこにある ` panic! ` が意味するものは、` unwrap ` が合成可能ではない、つまり、陶器店の中の雄牛だということです。
324
324
325
325
<!-- - ### Composing `Option<T>` values -->
@@ -373,12 +373,12 @@ fn extension_explicit(file_name: &str) -> Option<&str> {
373
373
<!-- tiresome. -->
374
374
このコードはいたってシンプルですが、ひとつだけ注目して欲しいのは、` find ` の型が不在の可能性について考慮することを強制していることです。
375
375
これは良いことです。なぜなら、コンパイラが私たちに、ファイル名が拡張子を持たないケースを、うっかり忘れないようにしてくれるからです。
376
- しかし一方で、 ` extension_explicit ` でしたような明示的なケース分析を毎回続けるのは 、なかなか面倒です。
376
+ しかし一方で、 ` extension_explicit ` でしたような明示的な場合分けを毎回続けるのは 、なかなか面倒です。
377
377
378
378
<!-- In fact, the case analysis in `extension_explicit` follows a very common -->
379
379
<!-- pattern: *map* a function on to the value inside of an `Option<T>`, unless the -->
380
380
<!-- option is `None`, in which case, just return `None`. -->
381
- 実は ` extension_explicit ` でのケース分析は 、ごく一般的なパターンである、` Option<T> ` への * map* の適用に当てはめられます。
381
+ 実は ` extension_explicit ` での場合分けは 、ごく一般的なパターンである、` Option<T> ` への * map* の適用に当てはめられます。
382
382
これは、もしオプションが ` None ` なら ` None ` を返し、そうでなけれは、オプションの中の値に関数を適用する、というパターンです。
383
383
384
384
<!-- Rust has parametric polymorphism, so it is very easy to define a combinator -->
@@ -401,7 +401,7 @@ fn map<F, T, A>(option: Option<T>, f: F) -> Option<A> where F: FnOnce(T) -> A {
401
401
402
402
<!-- Armed with our new combinator, we can rewrite our `extension_explicit` method -->
403
403
<!-- to get rid of the case analysis: -->
404
- 新しいコンビネータを手に入れましたので、 ` extension_explicit ` メソッドを書き直して、ケース分析を省きましょう :
404
+ 新しいコンビネータを手に入れましたので、 ` extension_explicit ` メソッドを書き直して、場合分けを省きましょう :
405
405
406
406
``` rust
407
407
# fn find (_ : & str , _ : char ) -> Option <usize > { None }
@@ -423,7 +423,7 @@ fn extension(file_name: &str) -> Option<&str> {
423
423
<!-- with any `Option<T>`: -->
424
424
もう一つの共通のパターンは、` Option ` の値が ` None ` だった時のデフォルト値を与えることです。
425
425
例えばファイルの拡張子がない時は、それを ` rs ` とみなすようなプログラムを書きたくなるかもしれません。
426
- ご想像の通り、このようなケース分析はファイルの拡張子に特有のものではありません 。
426
+ ご想像の通り、このような場合分けはファイルの拡張子に特有のものではありません 。
427
427
どんな ` Option<T> ` でも使えるでしょう:
428
428
429
429
``` rust
@@ -481,7 +481,7 @@ fn main() {
481
481
<!-- So, we are tasked with the challenge of finding an extension given a file -->
482
482
<!-- *path*. Let's start with explicit case analysis: -->
483
483
つまり、与えられたファイル * パス* から拡張子を見つけ出せるか、トライしなければなりません。
484
- まず明示的なケース分析から始めましょう :
484
+ まず明示的な場合分けから始めましょう :
485
485
486
486
487
487
``` rust
@@ -509,7 +509,7 @@ fn file_name(file_path: &str) -> Option<&str> {
509
509
<!-- *always* [rewrapped with `Some`](#code-option-map). Instead, we need something -->
510
510
<!-- like `map`, but which allows the caller to return another `Option`. Its generic -->
511
511
<!-- implementation is even simpler than `map`: -->
512
- ケース分析を減らすために単に ` map ` コンビネータを使えばいいと思うかもしれませんが、型にうまく適合しません。
512
+ 場合分けを減らすために単に ` map ` コンビネータを使えばいいと思うかもしれませんが、型にうまく適合しません。
513
513
なぜなら ` map ` が引数にとる関数は、中の値だけに適用されるからです。
514
514
そして関数が返した値は * 必ず* [ ` Some ` でラップされ直します] ( #code-option-map ) 。
515
515
つまりこの代わりに、 ` map ` に似ていながら、呼び出し元が別の ` Option ` を返せるしくみが必要です。
@@ -526,7 +526,7 @@ fn and_then<F, T, A>(option: Option<T>, f: F) -> Option<A>
526
526
```
527
527
528
528
<!-- Now we can rewrite our `file_path_ext` function without explicit case analysis: -->
529
- では、明示的なケース分析を省くように 、 ` file_path_ext ` を書き直しましょう:
529
+ では、明示的な場合分けを省くように 、 ` file_path_ext ` を書き直しましょう:
530
530
531
531
``` rust
532
532
# fn extension (file_name : & str ) -> Option <& str > { None }
@@ -544,15 +544,15 @@ fn file_path_ext(file_path: &str) -> Option<&str> {
544
544
<!-- semantics) for `Result`, which we will talk about next. -->
545
545
` Option ` 型には、他にもたくさんのコンビネータが [ 標準ライブラリで定義されています] [ 5 ] 。
546
546
それらの一覧をざっと眺めて、なにがあるか知っておくといいでしょう。
547
- 大抵の場合、ケース分析を減らすのに役立ちます 。
547
+ 大抵の場合、場合分けを減らすのに役立ちます 。
548
548
それらのコンビネータに慣れるための努力は、すぐに報われるでしょう。
549
549
なぜなら、そのほとんどは次に話す ` Result ` 型でも、(よく似たセマンティクスで)定義されているからです。
550
550
551
551
<!-- Combinators make using types like `Option` ergonomic because they reduce -->
552
552
<!-- explicit case analysis. They are also composable because they permit the caller -->
553
553
<!-- to handle the possibility of absence in their own way. Methods like `unwrap` -->
554
554
<!-- remove choices because they will panic if `Option<T>` is `None`. -->
555
- コンビネータは明示的なケース分析を減らしてくれるので 、 ` Option ` のような型をエルゴノミックにします。
555
+ コンビネータは明示的な場合分けを減らしてくれるので 、 ` Option ` のような型をエルゴノミックにします。
556
556
またこれらは * 不在の可能性* を、呼び出し元がそれに合った方法で扱えるようにするので、合成可能だといえます。
557
557
` unwrap ` のようなメソッドは、 ` Option<T> ` が ` None ` の時にパニックを起こすので、このような選択の機会を与えません。
558
558
@@ -752,7 +752,7 @@ fn main() {
752
752
<!-- This is a little better, but now we've written a lot more code! The case -->
753
753
<!-- analysis has once again bitten us. -->
754
754
これで少し良くなりましたが、たくさんのコードを書いてしまいました!
755
- ケース分析に 、またしてもやられたわけです。
755
+ 場合分けに 、またしてもやられたわけです。
756
756
757
757
<!-- Combinators to the rescue! Just like `Option`, `Result` has lots of combinators -->
758
758
<!-- defined as methods. There is a large intersection of common combinators between -->
@@ -920,14 +920,14 @@ fn double_number(number_str: &str) -> Result<i32> {
920
920
<!-- defined for `Result`. We can use these combinators to compose results of -->
921
921
<!-- different computations without doing explicit case analysis. -->
922
922
これまで話してきたのは ` Option ` のために定義されたコンビネータと、 ` Result ` のために定義されたコンビネータについてでした。
923
- これらのコンビネータを使うと、様々な処理の結果を明示的なケース分析なしに組み合わせることができました 。
923
+ これらのコンビネータを使うと、様々な処理の結果を明示的な場合分けなしに組み合わせることができました 。
924
924
925
925
<!-- Of course, in real code, things aren't always as clean. Sometimes you have a -->
926
926
<!-- mix of `Option` and `Result` types. Must we resort to explicit case analysis, -->
927
927
<!-- or can we continue using combinators? -->
928
928
もちろん現実のコードは、いつもこんなにクリーンではありません。
929
929
時には ` Option ` 型と ` Result ` 型が混在していることもあるでしょう。
930
- そんな時は、明確なケース分析に頼るしかないのでしょうか ?
930
+ そんな時は、明示的な場合分けに頼るしかないのでしょうか ?
931
931
それとも、コンビネータを使い続けることができるのでしょうか?
932
932
933
933
<!-- For now, let's revisit one of the first examples in this chapter: -->
@@ -1048,7 +1048,7 @@ fn ok_or<T, E>(option: Option<T>, err: E) -> Result<T, E> {
1048
1048
いままで ` unwrap ` を使わないよう説得してきたわけですが、最初にコードを書くときには ` unwrap ` が便利に使えます。
1049
1049
こうすることで、エラーハンドリングではなく、本来解決すべき課題に集中できます。
1050
1050
それと同時に ` unwrap ` は、適切なエラーハンドリングが必要とされる場所を教えてくれます。
1051
- ここから始ることをコーディングへの取っ掛かりとしましょう 。
1051
+ ここから始めることをコーディングへの取っ掛かりとしましょう 。
1052
1052
その後、リファクタリングによって、エラーハンドリングを改善していきます。
1053
1053
1054
1054
``` rust,should_panic
@@ -1116,7 +1116,7 @@ fn main() {
1116
1116
<!-- useful way of reporting an error. Thus, we must start by changing the return -->
1117
1117
<!-- type from `i32` to something else. -->
1118
1118
まず最初に ` file_double ` 関数をリファクタリングしましょう。
1119
- この関数を、この課題の他の構成要素と合成可能にするためには 、上記の問題のいずれかに遭遇しても、パニック * しない* ようにしなければなりません。
1119
+ この関数を、このプログラムの他の構成要素と合成可能にするためには 、上記の問題のいずれかに遭遇しても、パニック * しない* ようにしなければなりません。
1120
1120
これは実質的には、なにかの操作に失敗した時に、この関数が * エラーを返すべき* であることを意味します。
1121
1121
ここでの問題は、` file_double ` のリターン型が ` i32 ` であるため、エラーの報告には全く役立たないことです。
1122
1122
従ってリターン型を ` i32 ` から別の何かに変えることから始めましょう。
@@ -1225,7 +1225,7 @@ fn main() {
1225
1225
<!-- explicit case analysis. -->
1226
1226
前の節で使ったコードを、 * 早期のリターン* を使って書き直してみようと思います。
1227
1227
早期のリターンとは、関数の途中で抜けることを指します。
1228
- ` file_double ` のクロージャの中にいる間は、早期のリターンはできないので、明示的なケース分析までいったん戻る必要があります 。
1228
+ ` file_double ` のクロージャの中にいる間は、早期のリターンはできないので、明示的な場合分けまでいったん戻る必要があります 。
1229
1229
1230
1230
``` rust
1231
1231
use std :: fs :: File ;
@@ -1263,17 +1263,17 @@ fn main() {
1263
1263
<!-- function and returns the error (by converting it to a string). -->
1264
1264
このコードが、コンビネータを使ったコードよりも良くなったのかについては、人によって意見が分かれるでしょう。
1265
1265
でも、もしあなたがコンビネータによるアプローチに不慣れだったら、このコードのほうが読みやすいと思うかもしれません。
1266
- ここでは明示的なケース分析を ` match ` と ` if let ` で行っています。
1266
+ ここでは明示的な場合分けを ` match ` と ` if let ` で行っています。
1267
1267
もしエラーが起きたら関数の実行を打ち切って、エラーを(文字列に変換してから)返します。
1268
1268
1269
1269
<!-- Isn't this a step backwards though? Previously, we said that the key to -->
1270
1270
<!-- ergonomic error handling is reducing explicit case analysis, yet we've reverted -->
1271
1271
<!-- back to explicit case analysis here. It turns out, there are *multiple* ways to -->
1272
1272
<!-- reduce explicit case analysis. Combinators aren't the only way. -->
1273
1273
でもこれって逆戻りしてませんか?
1274
- 以前は、エラーハンドリングをエルゴノミックにするために、明示的なケース分析を減らすべきだと言っていました 。
1275
- それなのに、今は明示的なケース分析に戻ってしまっています 。
1276
- すぐにわかりますが、明示的なケース分析を減らす方法は * 複数* あるのです。
1274
+ 以前は、エラーハンドリングをエルゴノミックにするために、明示的な場合分けを減らすべきだと言っていました 。
1275
+ それなのに、今は明示的な場合分けに戻ってしまっています 。
1276
+ すぐにわかりますが、明示的な場合分けを減らす方法は * 複数* あるのです。
1277
1277
コンビネータが唯一の方法ではありません。
1278
1278
1279
1279
<!-- ## The `try!` macro -->
@@ -1284,7 +1284,7 @@ fn main() {
1284
1284
<!-- abstracts *control flow*. Namely, it can abstract the *early return* pattern -->
1285
1285
<!-- seen above. -->
1286
1286
Rustでのエラー処理の基礎となるのは ` try! ` マクロです。
1287
- ` try! ` マクロはコンビネータと同様、ケース分析を抽象化します 。
1287
+ ` try! ` マクロはコンビネータと同様、場合分けを抽象化します 。
1288
1288
しかし、コンビネータと異なるのは * 制御フロー* も抽象化してくれることです。
1289
1289
つまり、先ほど見た * 早期リターン* のパターンを抽象化できるのです。
1290
1290
@@ -1311,7 +1311,7 @@ macro_rules! try {
1311
1311
<!-- it does the case analysis and the early return for us, we get tighter code that -->
1312
1312
<!-- is easier to read: -->
1313
1313
` try! ` マクロを使うと、最後の例をシンプルにすることが、とても簡単にできます。
1314
- ケース分析と早期リターンを肩代わりしてくれますので 、コードが締まって読みやすくなります。
1314
+ 場合分けと早期リターンを肩代わりしてくれますので 、コードが締まって読みやすくなります。
1315
1315
1316
1316
``` rust
1317
1317
use std :: fs :: File ;
@@ -1395,14 +1395,14 @@ fn main() {
1395
1395
これは * 構造化されたデータ* で、IO操作において何が失敗したのかを示します。
1396
1396
エラーによって違った対応を取りたいこともあるので、このことは重要です。
1397
1397
(例: あなたのアプリケーションでは ` BrokenPipe ` エラーは正規の手順を踏んだ終了を意味し、 ` NotFound ` エラーはエラーコードと共に異常終了して、ユーザーにエラーを表示することを意味するかもしれません。)
1398
- ` io::ErrorKind ` なら、呼び出し元でエラーの種類を調査するために、ケース分析が使えます 。
1398
+ ` io::ErrorKind ` なら、呼び出し元でエラーの種類を調査するために、場合分けが使えます 。
1399
1399
これは ` String ` の中からエラーの詳細がなんだったのか探りだすことよりも、明らかに優れています。
1400
1400
1401
1401
<!-- Instead of using a `String` as an error type in our previous example of reading -->
1402
1402
<!-- an integer from a file, we can define our own error type that represents errors -->
1403
1403
<!-- with *structured data*. We endeavor to not drop information from underlying -->
1404
1404
<!-- errors in case the caller wants to inspect the details. -->
1405
- ファイルから整数値を取り出す例で ` String ` をエラー型として用いた代わりに、独自のエラー型を定義し、 * 構造化データ * によってエラー内容を表すことができます。
1405
+ ファイルから整数値を取り出す例で ` String ` をエラー型として用いた代わりに、独自のエラー型を定義し、 * 構造化されたデータ * によってエラー内容を表すことができます。
1406
1406
呼び出し元が詳細を検査したい時に備え、大元のエラーについての情報を取りこぼさないよう、努力してみましょう。
1407
1407
1408
1408
<!-- The ideal way to represent *one of many possibilities* is to define our own -->
0 commit comments