Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rustハンズオン @ Rust CA 1 Day Youth Boot Camp

Yuki Toyoda
December 18, 2021
4k

Rustハンズオン @ Rust CA 1 Day Youth Boot Camp

Yuki Toyoda

December 18, 2021
Tweet

Transcript

  1. 目次 ■ 自己紹介 ■ Rustとはどのような言語か? ■ 基本的な文法の解説 o Hello, world

    の実装 o FizzBuzz の実装 ■ 実践編 o cat コマンドの実装 o grep コマンドの実装
  2. 目次 ■ 自己紹介 ■ Rustとはどのような言語か? ■ 基本的な文法の解説 o Hello, world

    の実装 o FizzBuzz の実装 ■ 実践編 o cat コマンドの実装 o grep コマンドの実装
  3. 自己紹介 ■ 豊田優貴 (ユキさんとよく呼ばれる) ■ 株式会社サイバーエージェント o ソフトウェアエンジニア@AI 事業本部 Dynalyst

    o Rust 領域における Next Expert ■ 共著『実践Rustプログラミング入門』 ■ コミュニティオーガナイザー o Rust.Tokyo o RustFest Global ■ その他、OSS コントリビューションなど
  4. 普段の仕事で何を作っているか ■ 入社後、ずっと広告配信プロダクトの担当をしている。 o 〜2020年: 位置情報広告配信 AirTrack テックリード o 2021年〜:

    リターゲティング広告配信 Dynalyst ■ 速度と安定性が求められる Real-Time Bidding (RTB) の世界。 o ほとんどのレスポンスを安定して100ms以内に返す必要がある。 o リクエスト量は平均して秒間数十万リクエストに達する。 ■ ソフトウェアエンジニアとして、ほぼすべての領域をこなす。 o フロント、バックエンド、インフラまですべてのタスクをこなす。 o ちなみに、チームメンバーもだいたいすべての領域ができる。 o 強いて言うなら Scala エンジニア。
  5. 目次 ■ 自己紹介 ■ Rustとはどのような言語か? ■ 基本的な文法の解説 o Hello, world

    の実装 o FizzBuzz の実装 ■ 実践編 o cat コマンドの実装 o grep コマンドの実装
  6. Rust とは It wasn’t always so clear, but the Rust

    programming language is fundamentally about empowerment: no matter what kind of code you are writing now, Rust empowers you to reach farther, to program with confidence in a wider variety of domains than you did before. すぐにはわかりにくいかもしれませんが、Rustプログラミング言語は、エンパワーメント (empowerment)を根本原理としています: どんな種類のコードを現在書いているにせよ、Rustは幅広 い領域で以前よりも遠くへ到達し、 自信を持ってプログラムを組む力を与え(empower)ます。 -- The Rust Programming Language
  7. Rust とは A language empowering everyone to build reliable and

    efficient software Rust は信頼がおけて効率のよいソフトウェアを作れるように開発者をエンパワメントする言語です。 -- Rust 公式
  8. Rust とは A language empowering everyone but especially folks who

    didn’t think systems programming was for them Rust はシステムプログラミングは自分の領域だとは思っていなかった人々をとくにエンパワメントする言 語です。 -- Ashley Williams (Rust Core Team member, Rust Foundation Lead)
  9. Rust とは ■ Rust の中心概念は「empowerment」です。 o em: en-。提供するとか、文脈によって変わる英語の接頭辞。power: 力。 o

    つまり、「力を与えること」。 o Rust という強力な武器で、信頼性と安全性の高いソフトウェアの構築をできる、という 力を開発者に与えるプログラミング言語。 o これまでシステムプログラミングには縁がなかったプログラマであっても、安全で信頼に 値する方法でシステムプログラミングへの道を開いてくれる言語である。 o 低レイヤーのプログラマだけでなく、十分な表現力をもって、あらゆるレイヤーのプログ ラマに力を与える言語でもある。 ■ Rust という新しい武器を手に入れ、力を手にしましょう。 o というのが、本日の主題でもあります。
  10. これまで低レイヤーな領域で起きていたこと ■ メモリ安全性を担保できない実装がある。 o null ポインタのデリファレンス o dangling ポインタ(use-after-free, double

    free) o 未初期化状態のメモリを使用する o バッファオーバーフローなど。 ■ メモリ起因の脆弱性は実プロダクトでも問題になる。 o Google Chrome の脆弱性の約70%はメモリ起因だった。 o など。
  11. Rust のメリット ■ 性能のよさ o メモリ使用量が小さい。 o とても速い。 ■ 実行時ではなくコンパイルタイムに下記の安全性を担保できる。

    o メモリ管理を安全に行える ▸ 脆弱性の節で解説した話が起こりにくい。 ▸ 普段書く際は、メモリのことをあまり意識しなくてよい仕組みが裏にある。 o 並行処理を安全に行える ▸ データ競合が起こらない。 ▸ スレッドセーフなデータしか共有できない。
  12. Rust のメリット ■ プログラマの生産性を高めるツール群が充実している o 具体的には cargo というビルドツールひとつですべてが済む。 o このおかげで、サードパーティライブラリの利用が容易。

    o クロスプラットフォームビルドも手軽に行える。 o 標準リンタ (clippy) やフォーマッタ (rustfmt) が揃っている。 o LSP (rust-analyzer) がかなりよくできている。 ■ オープンマインドでプロフェッショナルなコミュニティ o 最近少し揉めていたが、揉めごともきちんと議論して前に進めようとする。 o ユーザーからの提案がとても歓迎される。コンパイラの開発は誰でも参加できる。
  13. Rust のデメリット ■ 循環的なデータ構造のモデリングが難しい o たとえば、循環構造をもつリンクリストを初心者のうちに作るのが難しい。 o データ構造のモデリングに Rust 特有のワークアラウンドを適用する必要がある。

    ■ コンパイルを通すのが時として難しい o コンパイルを通すまでが他の言語に比べると大変。 o ただ、エラーメッセージは親切。直し方を教えてくれる。 ■ 言語仕様が大きく、まだ拡大中で覚えることが多い o 機能が多く、いまでさえ発見がある。 o コンテキストを理解して適切に使いこなすのが難しいものがある。
  14. 期待される利用領域 ■ CLI ツール o クロスプラットフォームビルドの対応が楽にできるため。 o ripgrep, ytop など

    Linux の標準コマンドの置き換えツールが盛ん。 ■ 組み込みファームウェア開発 o 従来は C/C++ が大きなシェアを持っていた領域。 ■ システムプログラミング o OS やブラウザの実装などに利用されることもある。
  15. 期待される利用領域 ■ Web フロントエンド o JS/TSのツールの裏側がRustで実装されている事例が増えている。 o Web Assembly との相性がよい。

    ■ Web サーバーサイド開発 o 実は Rust の利用事例で一番多かったことが2019年のアンケートで判明。 o さまざまなサーバーサイド向けライブラリが登場している。 o 豊田も仕事で使用したことがあります。 ▸ その時の発表: https://speakerdeck.com/helloyuk13/rust-de-web- apurikesiyonhadokomadekai-fa-dekirufalseka
  16. 目次 ■ 自己紹介 ■ Rustとはどのような言語か? ■ 基本的な文法の解説 o Hello, world

    の実装 o FizzBuzz の実装 ■ 実践編 o cat コマンドの実装 o grep コマンドの実装
  17. 基本的な文法の解説 ■ 環境をセットアップする。 o Rust をインストールしよう! o VSCode と rust-analyzer

    を入れよう ■ 軽く動かしてみる。 o Hello, world してみよう ■ 変数宣言、制御構文、関数宣言 o let, let mut o if を使って FizzBuzz する o 関数を切り出して処理を共通化する o など。
  18. 基本的な文法の解説 ■ 環境をセットアップする。 o Rust をインストールしよう! o VSCode と rust-analyzer

    を入れよう ■ 軽く動かしてみる。 o Hello, world してみよう ■ 変数宣言、制御構文、関数宣言 o let, let mut o if を使って FizzBuzz する o 関数を切り出して処理を共通化する o など。
  19. エディタについて ■ 今日は VSCode を使用します。 o JetBrains 愛用者は、IntelliJ か CLion

    に Rust プラグインを入れる。 o VSCode ならトラブルシュートに協力できるかも…笑。 ■ VSCode に rust-analyzer というプラグインを入れてください。 o https://marketplace.visualstudio.com/items?itemName=matklad.rust -analyzer o Vim や Emacs などでも動作する。
  20. 基本的な文法の解説 ■ 環境をセットアップする。 o Rust をインストールしよう! o VSCode と rust-analyzer

    を入れよう ■ 軽く動かしてみる。 o Hello, world してみよう ■ 変数宣言、制御構文、関数宣言 o let, let mut o if を使って FizzBuzz する o 関数を切り出して処理を共通化する o など。
  21. Hello, world のコードを見てみよう ■ 後ほど解説するが、fn キーワードで関数を宣言できます。 o main という名前の関数は、実行時のエントリポイントです。 ■

    println! で標準出力ができます。 o ! はマクロであることを意味します。 ▸ マクロとは、Rust のプログラムをプログラミングする仕組みのことです。 ▸ コンパイルタイムでマクロ内のコードが展開・生成されます。 ▸ 他の言語ではメタプログラミングとも呼ばれます。 ■ Rust では、文・式・ブロックの末尾にセミコロンが基本的に必要です。 o ただし、セミコロンがない場合は特別視されます。 ▸ これは後ほど解説します。
  22. マクロの謎を解明する (質問を受けることが多いので) ■ マクロがコンパイルタイムで展開するコードを見ることができます。 o cargo expand というツールをインストール。 o デモ。

    ■ リフレクションとは違い、コンパイル時にコードが生成されます。 o 使うと Java 等のリフレクションと似ているように見えますが、少し違います。 ▸ リフレクションと比べると、もう少しできることが広いです。 ▸ Java 等のリフレクションは実行時に処理が走りますが、マクロはコンパイルタイムです。 ▸ Rust はできる限りコンパイルタイムに多くの物事を解決し、処理のオーバーヘッドを減らすこ とを目指しています。 ■ (少し専門的な話ですが) Rust のマクロは衛生的です。
  23. 基本的な文法の解説 ■ 環境をセットアップする。 o Rust をインストールしよう! o VSCode と rust-analyzer

    を入れよう ■ 軽く動かしてみる。 o Hello, world してみよう ■ 変数宣言、制御構文、関数宣言 o let, let mut o if を使って FizzBuzz する o 関数を切り出して処理を共通化する o など。
  24. 変数宣言をしてみよう ■ let で変数宣言をできます。束縛、と Rust ではいいます。 ■ Rust では変数宣言はデフォルトでイミュータブルです。 o

    イミュータブル (不変) : 再代入や破壊的変更をできないこと。 ■ 変数名の後ろに「: 型名」と書くと、型注釈をつけられます。 o Rust では型推論が強力なため、実際はほとんどつけることはありません。 ■ println! 内の {} は、変数を文字列内に代入するプレースホルダ。 o 余談: {} 以外にもいくつか種類があり、用途ごとに使い分けします。 ▸ https://doc.rust-lang.org/rust-by-example/hello/print.html
  25. 余談: なぜイミュータブルか ■ ミュータブルな実装は、変数のスコープが伸びたり、予期せぬ破壊的変更が加 えられたりし、メンテナンス性が高いとは言えないケースがあります。 o 金融系のシステムでは100万行を越えるような大規模開発をすることになりますが、そ こでスコープを絞ってさえいれば…というバグをいくつも見てきました。 o とくに並行・並列処理をする際には、予期せぬ破壊的変更が入らない保証を言語側でし

    てくれると大変ありがたいのです…。 ■ 一方で、すべてのケースでイミュータブルがよいわけではなく、スコープをし ぼってミュータブルな実装を採用するとよい場面もあります。 o たとえば、メモリ節約をしたいケースなどでは、ミュータブルな実装のほうが空間効率が よいケースがあります。
  26. よく見るプリミティブ型 (これ以外にもあります。詳しくはドキュメントをご覧ください。) i8, i16, i32, i64 符号付き整数型 u8, u16, u32,

    u64 符号なし整数型 f32, f64 浮動小数点数型 isize / usize CPUアーキテクチャごとのビットサイズ。 bool ブール値。 &str, String 文字列を扱う際によく利用される。後述。
  27. 文字列型 ■ String と &str の使い分けは、最初の鬼門になります。 o どっちがどっちかわかりにくいので、よく聞かれます。 o そのため、今日はとくに文字列型を絞って解説します。

    ■ なぜ多いかというと、Rust はシステムプログラミング言語だから。 o 他の言語と比較すると、よりさまざまなケースに対応する必要があるから。 ▸ UTF-8 の文字列を処理するための String, &str ▸ OS からの文字列の受け取りをする OsString (など) ▸ C コードからの文字列の受け取りをする CString (など) 他にもこれだけの文字列型がある…
  28. 文字列型 ■ String と &str の使い分けは、最初の鬼門になります。 o どっちがどっちかわかりにくいので、よく聞かれます。 o そのため、今日はとくに文字列型を絞って解説します。

    ■ なぜ多いかというと、Rust はシステムプログラミング言語だから。 o 他の言語と比較すると、よりさまざまなケースに対応する必要があるから。 ▸ UTF-8 の文字列を処理するための String, &str ▸ OS からの文字列の受け取りをする OsString (など) ▸ C コードからの文字列の受け取りをする CString (など)
  29. 文字列型 – 基本 ■ String o UTF-8 のテキストを保持する。 o ヒープメモリにアロケートされる。

    o リサイズできる。要するにミュータブル。 ■ &str o いわゆるスライス。 o 機械語生成時にすでに確保済みのメモリ領域にアロケートされる。 o 読み取り専用なので、リサイズできない。要するにイミュータブル。
  30. 文字列型 – 選び方 ■ UTF-8 文字列か? ■ ミュータブルな文字列か? o Yes:

    String o No: &str UTF-8 文字列? ミュータブルに したい? &str を使う String を使う はい いいえ
  31. 文字列型 – 選び方 ■ UTF-8 文字列か? ■ ミュータブルな文字列か? o Yes:

    String o No: &str UTF-8 文字列? ミュータブルに したい? &str を使う String を使う はい いいえ
  32. 文字列型 – 選び方 ■ UTF-8 文字列か? ■ ミュータブルな文字列か? o Yes:

    String o No: &str UTF-8 文字列? ミュータブルに したい? &str を使う String を使う はい いいえ
  33. 文字列型 – 選び方 ■ UTF-8 文字列か? ■ ミュータブルな文字列か? o Yes:

    String o No: &str UTF-8 文字列? ミュータブルに したい? &str を使う String を使う はい いいえ
  34. &str ■ 下記のコードは下記の図のようなメモリ確保をされます。 Stack buffer length 8 u t r

    i l t o a preallocated read-only memory length ※ preallocated read-only memory: 機械語生成時にすでに確保済みのメモリ領域を指す。
  35. 余談: スタックメモリとヒープメモリ ■ スタックメモリ o ローカル変数や関数からの処理の戻り先、引数と言った一時的なデータを保持。 o サイズを指定してメモリを確保する必要がある。 o スタックのようにメモリを管理するのでシンプル。

    o 速い。 ■ ヒープメモリ o プロセスが動的に確保する領域で、柔軟性が高い。 o C 言語で言う malloc で確保される領域にあたる。 o 明示的に解放されるまで (free) は使い続けられる。 o スタックメモリよりは遅い。
  36. 余談: Rust では ■ Rust の場合は、指示しない限りはスタックメモリで処理される。 o 本日最後の方に、実際にスタックに積まれる様子を図示します。 ■ ただ一部、ヒープを利用するものがある。

    o Vec のように動的に領域を確保する必要があるものや、 o Box のようにそもそもヒープに割当することを明示的にやるものがある。
  37. 基本的な文法の解説 ■ 環境をセットアップする。 o Rust をインストールしよう! o VSCode と rust-analyzer

    を入れよう ■ 軽く動かしてみる。 o Hello, world してみよう ■ 変数宣言、制御構文、関数宣言 o let, let mut o if を使って FizzBuzz する o 関数を切り出して処理を共通化する o など。
  38. FizzBuzz を通じて制御構文や関数を学ぶ ■ FizzBuzz: よくプログラマがやる遊びのひとつです。 o 3で割り切れる数のとき→ Fizz と出力 o

    5で割り切れる数のとき→ Buzz と出力 o 3で割り切れるかつ、5で割り切れる数のとき→ FizzBuzz と出力 ■ この節では、if, for, 関数への切り出し方などを学びます。 ■ 関数型プログラミング的なアプローチも身につけます。
  39. for 式を使って0〜99の数字をイテレートする ■ 0..100と書くと、0以上100未満の範囲を示すオブジェクト(Range)を生 成できます。 o num に0〜99の値が1つずつ流れ込みます。 o 裏側は

    Range という構造体です。ただ、これは糖衣構文です。 ▸ https://doc.rust-lang.org/std/ops/struct.Range.html ■ for はイテレータを回す糖衣構文になっています。 o Range はイテレータの性質をもちます。 o 応用: Iterator トレイトを実装しています。 ▸ https://doc.rust-lang.org/std/iter/trait.Iterator.html
  40. 関数に切り出す ■ fn と宣言すると関数を宣言できます。 o 関数名は snake_case です。 o 引数は「仮引数名:

    型名」で定義できます。 o 返り値(戻り値)は -> という記号のあとに書きます。 ■ セミコロンを書かない末尾の文が値を返すことを示し、return は不要です。 o セミコロンセンシティブな文法なので、少し好みは分かれるかも。 o 不要ではありますが、return を書くことはできます。ほとんど書かないけど。 o アーリーリターンしたい場合には return は必須になります。
  41. 関数型プログラミング的なアプローチ ■ これまでは for 式を用いた手続き型的なプログラミングをしました。 ■ Rust は関数型プログラミングの手法をいくつか取り入れています。 o map,

    filter, fold などです。Rustでは、これらをアダプタと呼びます。 ■ それらを使用することで、再利用性の高いコードを書くことができます。
  42. 関数型プログラミング的なアプローチ ■ 0〜99のイテレータを作成し、その結果を fizzbuzz 関数に通します。 ■ map で fizzbuzz 関数を実行し、i32

    -> String のマッピングをします。 ■ fold で結果生成される文字列を結合していき、まとめます。 o |...| で囲まれた部分はクロージャーと呼びます。 ▸ 他の言語ではラムダ式とも呼ぶかもしれません。
  43. 関数型プログラミング的なアプローチ ■ 0〜99のイテレータを作成し、その結果を fizzbuzz 関数に通します。 ■ map で fizzbuzz 関数を実行し、i32

    -> String のマッピングをします。 ■ fold で結果生成される文字列を結合していき、まとめます。 o |...| で囲まれた部分はクロージャーと呼びます。 ▸ 他の言語ではラムダ式とも呼ぶかもしれません。
  44. 関数型プログラミング的なアプローチ ■ 0〜99のイテレータを作成し、その結果を fizzbuzz 関数に通します。 ■ map で fizzbuzz 関数を実行し、i32

    -> String のマッピングをします。 ■ fold で結果生成される文字列を結合していき、まとめます。 o |...| で囲まれた部分はクロージャーと呼びます。 ▸ 他の言語ではラムダ式とも呼ぶかもしれません。
  45. 関数型プログラミング的なアプローチ ■ 0〜99のイテレータを作成し、その結果を "zzbuzz 関数に通します。 ■ map で "zzbuzz 関数を実行し、i32

    -> String のマッピングをします。 ■ fold で結果生成される文字列を結合していき、まとめます。 o |...| で囲まれた部分はクロージャーと呼びます。 ▸ 他の言語ではラムダ式とも呼ぶかもしれません。
  46. cat コマンド実装の目次 ■ プロジェクトを作成する。 ■ main.rs 自身を表示するプログラムを書く。 o パターンマッチングの解説 o

    Result 型を用いたエラーハンドリングの解説。 ■ ファイルパスを渡し、そのファイルを表示するプログラムを書く。 o Option 型を用いた実装の解説。 o if let 構文の解説。
  47. main.rs 自身を表示するプログラムを書く ■ read_to_string 関数 o パスの内容を読み込んで、String 型にして返します。 ■ use

    o 他の言語で言う import と同じで、モジュールを読み込みます。 ■ match o パターンマッチという文法です。 o Ok や Err は Result 型という enum のバリアントです。
  48. パターンマッチ ■ 他の言語でいう switch 文をもう少し強力にしたものです。 ■ パターンマッチは式なので、値を返すことができます。 ■ Rust では多くの型がパターンマッチに対応しています。

    o 構造体 (このあと説明します) o enum o 文字列型 (String など) o 数値 (i32 など) o ベクタ (Vec<T>) o その他、さまざまな型をパターンマッチで処理できます。
  49. Rust のエラーハンドリング ■ Result 型は Ok か Err をバリアントにもつ enum

    です。 o enum は Rust で非常によく出るパターンです。 ▸ 少し専門的な話: Ok や Err は代数的データ型 (ADT) と呼ばれます。 ▸ 数学的注釈: enum は直和集合です。 o enum はパターンマッチングできます。 ▸ Ok(content) で、content という変数に内容を持ちます。 ▸ Err(reason) の場合は、reason という変数にエラー内容が入ります。
  50. 今回記述が増えた内容について ■ std::env::args を使うと、実行時引数の取り出しができます。 o nth 関数で実行時引数を取り出します。 ■ Some, None

    は Option 型のバリアントです。 o 値がない可能性があることを示します。他の言語では null だったり nil だったり。 o Option 型も enum なので、パターンマッチできます。
  51. 今回記述が増えた内容について ■ std::env::args を使うと、実行時引数の取り出しができます。 o nth 関数で実行時引数を取り出します。 ■ Some, None

    は Option 型のバリアントです。 o 値がない可能性があることを示します。他の言語では null だったり nil だったり。 o Option 型も enum なので、パターンマッチできます。
  52. 今回記述が増えた内容について ■ std::env::args を使うと、実行時引数の取り出しができます。 o nth 関数で実行時引数を取り出します。 ■ Some, None

    は Option 型のバリアントです。 o 値がない可能性があることを示します。他の言語では null だったり nil だったり。 o Option 型も enum なので、パターンマッチできます。
  53. 今回記述が増えた内容について ■ std::env::args を使うと、実行時引数の取り出しができます。 o nth 関数で実行時引数を取り出します。 ■ Some, None

    は Option 型のバリアントです。 o 値がない可能性があることを示します。他の言語では null だったり nil だったり。 o Option 型も enum なので、パターンマッチできます。
  54. if let ■ 「値があるケースだけ特定の処理をしたい」場面に多々出会います。 ■ その場合は None 側は不要になりますが、パターンマッチでは冗長です。 ■ if

    let という構文を使用することができます。 o 実は変数束縛のタイミングでパターンマッチングが走っています。
  55. grep コマンド実装の目次 ■ 指定した文字列がある行を検索&出力できるプログラムを書く。 ■ grep に使用する引数を構造体にまとめる。 o 構造体の使い方の解説。 o

    構造体に対して実装を生やす方法の解説。 o 複数ファイル扱えるようにする。 ■ structopt を使った実行時引数のパース。 o サードパーティークレートの使い方の解説。 o 所有権と借用の解説。 ■ grep の並列処理化。 o rayon を使った並列処理の実装。
  56. 指定した文字列がある行を検索し、出力する ■ grep 関数を作り、指定した文字列パターンに一致するかチェックします。 o as_str 関数で &str 型に変換します。これは contains

    が &str を求めるためです。 ■ .lines() 関数により、一行一行をイテレータとして回すことができます。 o なので、 for 式で一行ずつループさせられています。
  57. main 関数を修正する ■ (pattern, path) はタプルと呼ばれる文法です。 o いわゆる組で、配列とは違い異なる型の組をもたせられます。 ▸ 数に制限はありません。

    ▸ 応用: Rust の Unit 型は、要素0個のタプルです。 ▸ 数学的注釈: 直積集合と密接な関係にあります。 o タプルもパターンマッチ可能です。
  58. 構造体に実装を追加する ■ impl キーワードを使い、構造体に対する実装を定義できます。 o 「impl 構造体名」の順で定義できます。 ■ 今回定義する new

    はスタティックメソッドです。 o 後ほど main 関数から呼び出しします。 o これはいわゆる静的メソッドです。インスタンスには紐付かず、型に紐づきます。 o インスタンスに紐づくインスタンスメソッドについては、後ほど解説します。
  59. CLI ツールっぽくする ■ CLI (Command Line Interface) ツールっぽくしましょう。 o 普段使っている

    Linux コマンドのような入力の仕方をするツールです。 ■ structopt というクレートを使います。 o Rust では「ライブラリ」のことを「クレート (crate; 木箱)」と呼びます。 o cargo は積荷という意味ですが、その積荷のうちの一つに木箱がある…みたいな。
  60. structopt の設定を行う ■ #[derive(…)]や#[structopt(…)]は「アトリビュート」と呼ばれます。 o 他の言語だと「アノテーション」という名前かもしれません。 o derive(StructOpt)で、StructOpt トレイトを継承する、という意味です。 ▸

    トレイトはこのハンズオンでは紹介できませんが、他の言語でいう interface のようなもの です。 ▸ 応用: トレイトは型クラスです。 o structopt(…)は、手続きマクロと呼ばれるマクロです。 ▸ Procedural Macros。かなり応用的な話なので、ハンズオンでは省きます。 ▸ https://doc.rust-lang.org/reference/procedural-macros.html
  61. 所有権とは ■ Rust には GC がなく、リソースの解放は自動で行われます。 o どのタイミングかというと、関数やブロックの終了の箇所など。 o Borrow

    Checker というものが Rust にはあります。 ▸ これが、参照の二重解放や解放済み領域を使用していないかを自動でチェックします。 ▸ Rust の安全性の秘訣はここにあります。 ■ Rust には値の所有者がかならず1つだけ存在します。 o プログラミング中は、「誰が値をもっているか」を意識する必要があります。 ■ 所有者が移動することをムーブといいます。 o 今日は深くは説明しませんが、コピーが起きるものもあります (i32 などの型)。 ▸ コピーの場合、ムーブは起きません。Copy トレイトを実装したものはコピーが行われます。
  62. ちょっとコードをきれいにする ■ &String は &str に裏で暗黙に型変換されるので… o つまり、&String と書かずに、&str と書くことができる。

    ▸ pattern も path も、ミュータブルである必要はない。 ▸ さらにいうと、content もミュータブルである必要はない。 o ちょっと初心者の範囲を超えているので深くは踏み入らない。 ▸ 参考になるかも: https://qiita.com/nirasan/items/e9c621240a7aae914cb8 o grep 関数についているこれらをすべて修正できる。
  63. 今回紹介できなかった機能 ■ 今回時間の都合で紹介できなかった機能がいくつかあります。下記です。 o ライフタイム o トレイト o ジェネリクス o

    スマートポインタ (Box, Rc, RefCell など) o 並行処理にまつわる機能 (Send, Sync) o ユニットテスト o モジュール、など ■ これらをより掘り下げたい方は、拙作ですが下記のブログをどうぞ。 o https://blog-dry.com/entry/2021/01/23/141936
  64. どちらかを選んで取り組んでみましょう ■ Grep に拡張コマンドを追加する。 o 「行番号」を表示する n (line-number) オプションを実装してみる。 o

    grep の man page を眺めて、いくつかオプションを実装してみる。 ■ 自分の好きなものを実装してみる。 o ご自身のお好きなものを実装してみましょう!
  65. 参考文献など ■ このハンズオンの演習問題の多くは下記のスライドに依っています。 o https://chikoski.info/rust-handson/ ■ 『詳解Rustプログラミング』 Tim McNamara /

    吉川邦夫 ■ 『Programming Rust Second Edition』 Jim Blandy 他 ■ The Rust Programming Language o https://doc.rust-lang.org/book/ ■ 『詳解Linuxカーネル 第3版』 Daniel P. Bovet 他 ■ Software Design 2021年9月号 o 連載: 「Rust でわかるメモリ管理」