15日から18日の分までのrustの勉強記録
TRPL pp.286-303
12章の続き
コマンドラインオプションではなく、代わりに環境変数を使用するように変更する
TDD:
- 失敗するテストを書く
- 古いテストを変更し、すでに実装済みの機能を誤って壊してしまわないことを保証
- 失敗する実装を作る
- 実装する
使っていたメソッド:
to_lowercase
- Stringを返す。
- 新しいデータ、新しいStringのメモリを確保している
- Stringを返す。
contains
- これのシグニチャは文字列slice
- なので、Stringを渡すときは
&
をつける必要があった
- なので、Stringを渡すときは
- これのシグニチャは文字列slice
env::var
を使う- 環境変数がsetされていたらOk列挙子を
- セットされていなかったらErr列挙子を返す
is_err
を使う- Errだったらtrueを返す
- この場合は、セットされていたらfalseを返すことになる。
- 値は関係ない場合は、unwrap, expect, Resultのメソッドは使う必要はない
- Errだったらtrueを返す
引数と環境変数で同じ設定を行うことができるプログラム、そして、どちらが優先されるかを決定している、そんなプログラムを作る課題は解いた。
出力について
- 標準出力(stdout): 普通の情報用
- 標準エラー出力(stderr): エラーメッセージ用
この差異のおかげで、エラーメッセージを画面に表示しつつ、プログラムが成功して出力をファイルに李大レスことすることをユーザーは選択できる。
どのように標準出力に書き込まれているか。
- 標準エラーストリームはリダイレクトせず、全て画面に表示され続ける
- コマンドラインプログラムはエラーメッセージを標準エラー出力に送信することを期待する
- 標準出力の場合、
>
とfile名
でfile名のfileにリダイレクトされ、保存される
求めるもの: エラーメッセージは標準エラーに出力され、成功した状態のデータのみはファイルに残ること
標準エラーストリームに出力するマクロeprintln!
(標準出力ストリームではない)
13章
関数型言語に影響された機能の一部、
- クロージャ: 変数に保存できる関数に似た文保要素
- イテレータ: 一連の要素を処理する方法
クロージャ
クロージャは
- 変数に保存したり、引数として他の関数に渡すことのできる匿名関数
- ある場所でクロージャを生成し、
- そこから別の文脈でクロージャを呼び出して評価できる
- 関数と異なり、呼び出されたスコープの値をキャプチャできる
時間のかかる関数を2回呼び出しているケースで、どうやってリファクタしていくかで使い方を学んでいく。
関数でリファクタリング
関数への重複した呼び出しの結果を変数に抽出しよう
結果が本当に必要なところだけコードを実行したい
クロージャでリファクタリング
呼び出しの結果を保存するのではなく、コードを定義するクロージャを変数に保存する
let name = |x| {
...
v
};
- クロージャーのlet文は
- 結果の値ではなく、
- 匿名関数の定義を含むことを意味する
- let文なので末尾に
;
が必要 - 一組の縦棒で、縦棒の中にクロージャーの仮引数を指定
- 関数の定義と同様に
- クロージャー本体が式1つなら
{
、}
を省略可能 {...}
で関数の本体を書く- 返り値を返すなら最終行に指定
- クロージャー本体が式1つなら
- クロージャは関数のように呼び出せる
複数回コードを呼び出す問題の再修正については、クロージャーが解決策を提供する。
クロージャ定義に型注釈がない理由、および、クロージャに関わるトレイトについて
- 関数
- ユーザーに露出する明示的なインターフェイスの一部
- 型を注釈する必要がある
- ユーザーに露出する明示的なインターフェイスの一部
- クロージャ
- 露出するインターフェイスには使用されない短く狭い文脈でのみ関係する
- 型を注釈する必要がない
- 注釈を加えることもできる
- 露出するインターフェイスには使用されない短く狭い文脈でのみ関係する
クロージャ定義には、引数それぞれと戻り値に大して推論される具体的な型が1つある。 だから、2つの異なる型でクロージャーの呼び出しを試みると、1つ目の呼び出しの時点で型が推論されるので、2つ目の呼び出しで型エラーとなる。