マインドマップギャラリー マスタリング RUST 第 2 版
これは、RUST をマスターするためのマインド マップです。上記の手順と提案を通じて、Rust プログラミング スキルを徐々に向上させ、Rust によってもたらされるメモリの安全性と効率的なパフォーマンスを楽しむことができます。
2024-04-04 15:14:48 に編集されましたRUSTに精通している
第 1 章 Rust の入門
1.1 Rust とは何か、そしてなぜそれが必要なのか
Rust は、Graydon Hoare によって 2006 年に作成され、リリースされた、高速で同時実行性が高く、安全で強力なプログラミング言語です。現在、これはオープンソース言語となり、主に Mozilla チームと多くのオープンソース コミュニティ メンバーによって維持および開発されています。
Rust には GitHub 上にオープンソース開発 Web サイトがあり、開発の勢いは非常に速いです。新しい機能は、コミュニティ主導の Request For Comment (RFC) プロセスを通じて言語に追加されます。このプロセスでは、誰でも新しい機能を送信して、RFC ドキュメントで詳細に説明できます。その後、RFC で合意が求められ、合意に達すると、機能は実装フェーズに入ります。
Rust は静的かつ強力に型付けされた言語として存在します。静的属性は、コンパイラがコンパイル時に関連するすべての変数と型に関する情報を持ち、コンパイル時に多くのチェックを行い、実行時には少量の型チェックのみを残すことを意味します。
1.2 Rustツールチェーンをインストールする
錆びた.rs
1.3 Rustの概要
1.3.1 プリミティブ型
ブール
これらは、true または false のいずれかとなる一般的なブール値です。
文字
キャラクター
整数
このタイプはビット幅が特徴です。 Rust でサポートされる最大長は 128 ビットです。
サイズ
可変サイズの符号付き整数 (サイズは基礎となるポインターのサイズによって異なります)。
使う
可変サイズの符号なし整数 (サイズは基礎となるポインターのサイズによって異なります)。
f32
f32ビット浮動小数点型
f64
f64ビット浮動小数点型
[T; N]
固定サイズの配列。T は要素の型を表し、N は要素の数を表し、コンパイル時の負ではない定数です。
[た]
連続シーケンスの動的サイズのビュー。T は任意のタイプを表します。
str
文字列のスライス。主に参照として使用されます。つまり、&str
(て、う、..)
有限シーケンス T と U は異なるタイプにすることができます。
fn(i32)->i32
i32 型パラメータを受け取り、i32 型パラメータを返す関数。関数にも型があります。
1.3.2 変数宣言と不変性
Rust では、キーワード let を使用して変数を宣言します。変数を初期化した後は、別の値を割り当てることはできません。後で変数を別の変数 (同じ型) にポイントする必要がある場合は、変数の前にキーワード mut を付ける必要があります。
1.3.3 機能
関数は、一連の命令を名前付きエンティティに抽象化し、後で他のコードから呼び出すことができ、ユーザーが複雑さを管理できるようにします。
fn add(a: u64, b: u64) -> u64 { ab } fn main() { a: u64 = 17; b = 3 とします。 let result = add(a, b); println!("結果 {}", 結果); }
関数は基本的に、値を返す式です。デフォルトでは、型 () (ユニット) の値になります。これは、C/C++ の void 戻り値の型に似ています。
1.3.4 閉鎖
Rust はクロージャーをサポートします。クロージャは関数に似ていますが、クロージャが宣言される環境またはスコープに関するより多くの情報を持っています。関数には名前が関連付けられていますが、クロージャの定義には名前が関連付けられていませんが、変数に割り当てることができます。 Rust の型推論のもう 1 つの利点は、ほとんどの場合、型なしでクロージャのパラメータを指定できることです。これは最も単純なクロージャ「let my_closure = ||();」です。何も行わないパラメータのないクロージャを定義します。その後、関数に似た my_closure() 経由でそれを呼び出すことができます。 2 つの垂直バー「||」は、|a、b| などのクロージャ パラメータを格納するために使用されます。 Rust が正しい型を認識できない場合、パラメータの型 (|a:u32|) を指定する必要がある場合があります。
fn main() { ダブラー = |x| x * 2 とします。 値 = 5 とします。 2回 = doubler(値); println!("{} を 2 倍にしたものは {}", value, 2 回); let big_closure = |b, c| { z = b c とします。 z * 2 回 }; some_number = big_closure(1, 2); とします。 println!("クロージャの結果: {}", some_number); }
1.3.5 文字列
文字列は、あらゆるプログラミング言語で最も一般的に使用されるデータ型の 1 つです。 Rust では通常、&str 型と String 型の 2 つの形式で表示されます。 Rust 文字列は、有効な UTF-8 エンコードされたバイト シーケンスであることが保証されています。これらは C 文字列のように NULL で終了せず、文字列の間に NULL バイトを含めることができます。
fn main() { let question = "調子はどうですか?"; let person: String = "Bob".to_string(); let namaste = String::from("zd"); println!("{}! {} {}", ナマステ, 質問, 人); }
上記のコードでは、人物とナマステのタイプは String で、質問のタイプは &str です。文字列型データを作成するにはさまざまな方法があります。文字列型データはヒープ上に割り当てられます。通常、これらの文字列はスタックおよびヒープ上にある、またはコンパイルされたオブジェクト コードのデータ セグメント内の文字列である可能性があります。
1.3.6 条件と判定
Rust の条件判断は他の言語の条件判断と似ており、C のような if else 構造に従います。
fn main() { 錆びる_is_awesome = trueにしましょう。 もし錆びが素晴らしいなら{ println!("確かに"); } それ以外 { println!("そうだ、Rust を試してみるべきだ!"); } }
Rust では、if 構文はステートメントではなく式です。一般的なプログラミング用語では、ステートメントは値を返しませんが、式は値を返します。この違いは、Rust の if else 条件が常に値を返すことを意味します。値のタイプは、empty () または実際の値です。中括弧の最後の行が何であっても、それが if else 式の戻り値になります。 if 分岐と else 分岐は同じ戻り値の型を持つ必要があることに注意することが重要です。
fn main() { let result = if 1 == 2 { 「待って、何?」 } それ以外 { 「錆には意味がある」 }; println!("ご存知ですか? {}.", result); }
割り当てられる値が if else 式から返される場合、終了マークとしてセミコロンを使用する必要があります。たとえば、 が式の場合、 let はステートメントであり、最後にセミコロンが必要です。
1.3.7 一致式
Rust の match 式は非常にシンプルで使いやすいです。基本的には C 言語の switch ステートメントの簡易版に似ており、ユーザーは変数の値と高度なフィルタリング機能の有無に基づいて判断できます。
fn req_status() -> u32 { 200 } fn main() { let status = req_status(); マッチステータス { 200 => println!("成功"), 404 => println!("見つかりません"), その他 => { println!("コード: {} でリクエストが失敗しました", other); } } }
各一致は同じ型を返す必要があります。さらに、一致する可能性のあるすべての値に対して完全一致を実行する必要があります。 Rust では、catch all 変数 (ここではその他) または _ (アンダースコア) を使用することで、残りの可能性を無視できます。
1.3.8 ループ
Rust で何かを繰り返し実行するには、loop、while、for という 3 つの構造を使用します。これらすべての構造には通常、キーワード continue と Break が含まれており、それぞれループをスキップしたり抜け出すことができます。
fn main() { mut x = 1024 とします。 ループ{ x < 0 の場合 { 壊す; } println!("あと {} 回残ります", x); x -= 1; } }
Rust でループを実行するための追加機能は、ループ コードのブロックに名前を付ける機能です。これは、break ステートメントを直接含むループだけでなく、2 つ以上のネストされたループがあり、そのいずれかから中断したい場合に使用できます。
fn sick_sub(a: i32, b: i32) -> i32 { mut の結果 = 0 とします。 'インクリメント: ループ { if 結果 == a { mut dec = b とします。 'デクリメント: ループ { ifdec==0{ ブレーク ' インクリメント; } それ以外 { 結果 -= 1; 12 進数 -= 1; } } } それ以外 { 結果 = 1; } } 結果 } fn main() { a = 10 とします。 b = 4 とします。 let result = 愚かなサブ(a, b); println!("{} マイナス {} は {}", a, b, result); }
Rust にもキーワード for があります。これは他の言語で使用される for ループに似ていますが、実装はまったく異なります。 Rust の for ループは基本的に、より強力な反復構造 (イテレータ) のための糖衣構文です。簡単に言えば、Rust の for ループはイテレータに変換できる型でのみ機能します。そのようなタイプの 1 つが Range タイプです。 Range タイプは一連の数値を参照できます。
fn main() { print!("通常の範囲: "); 私にとって 0..10 { print!("{},", i); } println!(); print!("包含範囲: "); for i in 0..=10 { print!("(),", i); } }
1.3.9 カスタムデータ型
カスタム タイプは、ユーザーによって定義されたタイプです。カスタム タイプは複数のタイプで構成できます。これらは、プリミティブ型または複数のカスタム型の組み合わせのラッパーにすることができます。これらには、構造体、列挙体、および共用体の 3 つの形式があり、構造体、列挙体、共用体とも呼ばれます。これにより、データをより簡単に表現できるようになります。カスタム型の命名規則は CamelCase に従います。
構造
Rust には 3 つの形式の構造体宣言があります。これらの中で最も単純なものはユニット構造体です。これはキーワード struct を使用して宣言され、その後にその名前が続き、セミコロンで終わります。
ダミー構造体; fn main() { 値 = ダミーにします。 }
構造の 2 番目の形式はタプル構造体で、これにはデータが関連付けられています。これらの各フィールドには名前がありませんが、定義内の位置に基づいて参照されます。
struct Color(u8, u8, u8); fn main() { 白 = Color(255, 255, 255); とします。 赤 = 白.0 とします。 緑 = 白.1 とします。 青 = 白.2 とします。 println!("赤色の値: {}", red); オレンジ = Color(255, 165, 0); とします。 Color(r, g, b) = オレンジとします。 println!("R: {}, G: {}, B: {} (オレンジ)", r, g, b); Color(r, _, b) = オレンジとします。 }
タプル構造は、属性が 5 つ未満のデータをモデル化する場合に最適です。これ以外の選択をすると、コードの読みやすさと推論が妨げられます。 3 つ以上のフィールドを持つデータ型の場合、C に似た言語を使用して構造を構築します。これは 3 番目の形式であり、最も一般的に使用される形式です。
構造体プレーヤー { 名前: 文字列、 iq:u8、 友達:u8、 スコア: U16 } fn bug_player_score(mut player: プレーヤー、スコア: u16) { player.score = スコア; println!("更新されたプレイヤー統計:"); } fn main() { let name = "アリス".to_string(); let player = プレイヤー { 名前, iq: 171、 友達: 134、 スコア: 1129 }; バンプ_プレーヤー_スコア(プレーヤー, 120); }
列挙する
列挙は、さまざまなタイプのものをモデル化する必要がある場合にこれを行うための良い方法です。これは、キーワード enum の後に列挙名と中括弧のペアを使用して作成されます。中括弧の中に、考えられるすべての型、つまりバリアントを書くことができます。これらのバリアントはデータの有無にかかわらず定義でき、含まれるデータは任意の far 型、構造体、タプル構造、さらには列挙型にすることもできます。
列挙型の方向 { Nさん E、 S、 W } enum PlayerAction { 動く { 方向: 方向、 スピード:u8 }、 待って、 攻撃(方向) } fn main() { let Simulated_player_action = PlayerAction::Move { 方向: 方向::N、 速度: 2、 }; シミュレートされたプレイヤーアクションの一致 { PlayerAction::Wait => println!("プレイヤーは待機を希望しています"), PlayerAction::Move { 方向、速度 } => { println!("プレーヤーは方向 {:?} に速度 {} で移動したいと考えています", 方向、速度) } PlayerAction::攻撃(方向) => { println!("プレイヤーは方向 {:?} を確認したい", 方向) } }; }
1.3.10 型に関する関数とメソッド
構造体の impl ブロック
コンストラクターのような関数とゲッター メソッドとセッター メソッドという 2 つのメカニズムを使用して、定義された構造に動作を追加できます。
構造体プレーヤー { 名前: 文字列、 iq:u8、 友達:u8 } impl プレーヤー { fn with_name(name: &str) -> プレーヤー { プレイヤー { 名前: name.to_string()、 iq: 100、 友達: 100 } } fn get_friends(&self) -> u8 { 自分自身、友達 } fn set friends(&mut self, count: u8) { self.friends = カウント; } } fn main() { let mut player = Player::with_name("Dave"); player.set_friends(23); println!("{} の友達数: {}", player.name, player.get_friends()); let _ = Player::get_friends(&player); }
関連メソッド: このメソッドには最初のパラメータとして self タイプがありません。これは、オブジェクト指向プログラミング言語の静的メソッドに似ています。これらのメソッドは型自体で呼び出すことができ、型のインスタンスを呼び出す必要はありません。関連するメソッドは、メソッド名の前に構造名と二重コロンを付けることによって呼び出されます。
インスタンス メソッド: self を最初の外部パラメータとして受け取る関数。ここでの self は Python の self に似ており、メソッドを実装するインスタンスを指します。
impl ブロックと列挙型
列挙型はステート マシンで広く使用されており、一致式とともに使用すると、状態遷移コードを非常に簡潔にすることができます。これらは、カスタム エラー タイプのモデリングにも使用できます。
enum 支払いモード { デビット、 クレジット、 ペイパル } fn pay_by_credit(amt: u64) { println!("{} のクレジット支払いを処理しています", amt); } fn pay_by_debit(amt: u64) { println!("{} のデビット支払いを処理しています", amt); } fn paypal_redirect(amt: u64) { println!("金額について PayPal にリダイレクトしています: {}", amt); } impl 支払いモード { fn pay(&self, 金額: u64) { 自分自身と一致する { PaymentMode::Debit => pay_by_debit(金額)、 PaymentMode::Credit => pay_by_credit(金額)、 PaymentMode::Paypal => paypal_redirect(金額) } } } fn get_saved_payment_mode() -> 支払いモード { 支払いモード::デビット } fn main() { letpayment_mode = get_saved_payment_mode(); 支払い_モード.支払い(512); }
1.3.11 モジュール、import および use ステートメント
プログラミング言語では、複雑さを管理するために、コードの大きなブロックを複数のファイルに分割する方法が提供されることがよくあります。 Java は、各 .java ファイルがパブリック クラスであるという規則に従い、C はヘッダー ファイルと include ステートメントを提供します。 Rust はモジュールメカニズムを提供します。モジュールは、Rust プログラムのコードに名前を付けて編成する方法です。
すべての Rust プログラムにはルート モジュールが必要です。実行可能ファイルの場合は通常 main.rs ファイルで、ライブラリの場合は通常 lib.rs ファイルです。
モジュールは、他のモジュール内で宣言したり、ファイルやディレクトリに編成したりできます。
コンパイラがモジュールを認識するには、ルート モジュールでキーワード use をモジュール名の前に使用する必要があります。これは、要素をスコープに含めることを意味します。
モジュールで定義された要素はデフォルトではプライベートであり、キーワード pub を使用して呼び出し元に公開する必要があります。
1.3.12 収集
配列
配列は固定長であり、同じ型の要素を格納できます。これらは [T, N] で表されます。ここで、T は任意の型を表し、N は配列要素の数を表します。配列のサイズは変数で表すことができず、usize のリテラル値である必要があります。
タプル
プロジェクト一覧
キーと値のペア
スライス
1.3.13 イテレータ
サブトピック
サブトピック
サブトピック
1.4 文字カウンターの改善
1.5 概要
第 2 章 Cargo を使用したプロジェクト管理
2.1 パッケージマネージャー
2.2 モジュール
2.2.1 ネストされたモジュール
2.2.2 ファイルをモジュールとして使用する
2.2.3 ディレクトリをモジュールとして使用する
2.3 貨物と図書館
2.3.1 新しい Cargo プロジェクトを作成する
2.3.2 貨物と依存関係
2.3.3 Cargo を使用したテストの実行
2.3.4 Cargo を使用してサンプルを実行する
2.3.5 貨物作業スペース
2.4 カーゴツールの拡張
2.4.1 サブコマンドと Cargo のインストール
2.4.2 Clippy を使用してコードをフォーマットする
2.4.3 Cargo.toml マニフェスト ファイルの概要
2.5 Rust開発環境をセットアップする
2.6 Cargo を使用して imgtool プログラムを構築する
2.7 概要
第 3 章 テスト、文書化、およびベンチマーク
3.1 テストの目的
3.2 テストの編成
3.3 単体テスト
3.3.1 最初の単体テスト
3.3.2 テストの実行
3.3.3 テストコードを分離する
3.3.4 故障テスト
3..3.5 テストを無視する
3.4 結合テスト
3.4.1 最初の結合テスト
3.4.2 共通コードの共有
3.5 ドキュメント
3.5.1 ドキュメントの作成
3.5.2 ドキュメントの生成と表示
3.5.3 ホストされるドキュメント
3.5.4 ドキュメントのプロパティ
3.5.5 文書化されたテスト
3.6 ベンチマーク
3.6.1 内蔵マイクロベンチマークツール
3.6.2 Rustの安定版でのベンチマーク
3.7 ソフトウェア パッケージの作成とテスト - ロジック ゲート シミュレーター
3.8 CI 統合テストと Travis CI
3.9 概要
第 4 章 タイプ、ジェネリック、および特性
4.1 型システムとその重要性
4.2 ジェネリックス
4.2.1 ジェネリックスの作成#
4.2.2 一般的な実装
4.2.3 一般的なアプリケーション
4.3 機能を使用して動作を抽象化する
4.3.1 特性
4.3.2 さまざまな形式の機能
4.4 パッケージの汎用機能の使用 - 機能間隔
4.4.1 タイプの特性間隔
4.4.2 ジェネリック関数と impl コード ブロックの特性区間
4.4.3 「 」機能の組み合わせを使用して間隔を形成する
4.4.4 特徴間隔と impl 特徴構文
4.5 標準ライブラリ機能の概要
4.6 特性オブジェクトを使用して真のポリモーフィズムを実現する
4.6.1 配布
4.6.2 特徴的なオブジェクト
4.7 概要
第 5 章 メモリ管理とセキュリティ
5.1 プログラムとメモリ
5.2 プログラムによるメモリの使用方法
5.3 メモリの管理と分類
5.4 メモリ割り当ての概要
5.4.1 スタック
5.4.2 ヒープ
5.5 メモリ管理の欠陥
5.6 メモリの安全性
5.7 メモリの安全性の 3 原則
5.7.1 所有権
5.7.2 特性による型の再利用
5.7.3 借用
5.7.4 借用ルールに基づくメソッドの種類
5.7.5 ライフサイクル
5.8 Rustのポインタ型
5.8.1 参照 - 安全なポインタ
5.8.2 生のポインタ
5.8.3 スマート ポインター
5.8.4 参照カウント型スマート ポインタ
5.8.5 内部変動の適用
5.9 概要
第6章 例外処理
6.1 例外処理の概要
6.2 回復可能な例外
6.2.1 オプション
6.2.2 結果
6.3 オプションと結果の組み合わせ
6.3.1 一般的なコンビネータ
6.3.2 コンバイナアプリケーション
6.3.3 オプション型と結果型の間の変換
6.4 早期復帰と演算子「?」
6.5 回復不可能な例外
6.6 カスタムエラーとエラー特性
6.7 概要
第 7 章 高度な概念
7.1 型システムの概要
7.1.1 コードブロックと式
7.1.2 let ステートメント
7.1.3 式としてのループ
7.1.4 数値型における型の明確さと記号の区別
7.1.5 型推論
7.1.6 型のエイリアス
7.2 文字列
7.2.1 所有権を含む文字列 - 文字列
7.2.2 文字列の借用—&str
7.2.3 文字列のスライスとチャンク化
7.2.4 関数での文字列の使用
7.2.5 文字列の連結
7.2.6 &str と String の適用シナリオ
7.3 グローバルな値
7.3.1 定数
7.3.2 静的な値
7.3.3 コンパイル時関数 — const fn
7.3.4 Lazy_static マクロによる動的静的値
7.4 イテレータ
7.5 高度なタイプ
7.5.1 不定長型
7.5.2 関数の種類
7.5.3 「!」を入力して関数をディスパッチしないでください。
7.5.4 結合
7.5.5 牛
7.6 高度な機能
7.6.1 サイズと?サイズ
7.6.2 借用とAsRef
7.6.3 骨抜き
7.6.4 出発地と到着地
7.6.5 特徴的なオブジェクトとオブジェクトのセキュリティ
7.6.6 一般的な関数呼び出し構文
7.6.7 フィーチャルール
7.7 高度なクロージャ
7.7.1 Fn クロージャ
7.7.2 FnMut クロージャ
7.7.3 FnOnce クロージャ
7.8 構造体、列挙型、特性の定数
7.9 モジュール、パス、インポート
7.9.1 インポート
7.9.2 再度インポートする
7.9.3 プライバシー
7.10 高度なマッチングパターンとガード
7.10.1 マッチガード
7.10.2 高度な let 構築
7.11 鋳造
7.12 型とメモリ
7.12.1 メモリの調整
7.12.2 std::mem モジュール
7.13 serde を使用したシリアル化と逆シリアル化
7.14 概要
第 8 章 同時実行性
8.1 プログラムの実行モデル
8.2 同時実行性
8.2.1 並行メソッド
8.2.2 欠陥
8.3 Rustにおける同時実行性
8.3.1 スレッドの基本
8.3.2 カスタムスレッド
8.3.3 スレッド内のデータへのアクセス
8.4 スレッド同時実行モデル
8.4.1 状態共有モデル
8.4.2 相互排除
8.4.3 Arc と Mutex による共有可変性
8.4.4 メッセージングによる通信
8.5 Rustにおけるスレッドセーフ
8.5.1 スレッドセーフとは何ですか?
8.5.2 スレッドセーフの特性
8.5.3 送信
8.5.4 同期
8.6 アクターモデルを使用した同時実行性の実装
8.7 その他のライブラリ
8.8 まとめ
第9章 マクロとメタプログラミング
9.1 メタプログラミングとは何ですか?
9.2 Rustマクロの応用シナリオ
9.3 Rustのマクロとその型
9.4 Macro_rules を使用してマクロを作成します。
9.5 標準ライブラリの組み込みマクロ
9.6macro_rules!
9.7 マクロ内の繰り返し
9.8 マクロの高度なアプリケーション - HashMap 初期化用の DSL の作成
9.9 マクロの使用例 - テストの作成
9.10 演習
9.11 プロセスマクロ
9.12 派生マクロ
9.13 高レベルマクロ
9.14 一般的に使用されるプロセス マクロ ソフトウェア パッケージ
9.15 概要
第 10 章 安全でない Rust と外部関数インターフェイス
10.1 安全性と危険性
10.1.1 安全でない関数とコードブロック
10.1.2 安全でない特性と実装
10.2 RustでのCコードの呼び出し
10.3 C言語を介したRustコードの呼び出し
10.4 Rustでの外部C/Cライブラリの使用
10.5 PyO3 を使用したネイティブ Python 拡張機能の構築
10.6 RustでのNode.jsのネイティブ拡張機能の作成
10.7 概要
第11章 ログ
11.1 ロギングとその重要性
11.2 ロギングフレームワークの要件
11.3 ロギングフレームワークとその機能
11.4 ロギング方法
11.4.1 非構造化ロギング
11.4.2 構造化ロギング
11.5 Rustへのログイン
11.5.1 ログ - Rust のロギング
11.5.2 env_logger
11.5.3 log4rs
11.5.4 構造化ログのための slog の使用
11.6 概要
第12章 Rustとネットワークプログラミング
12.1 ネットワークプログラミングの概要
12.2 同期ネットワーク I/O
12.3 非同期ネットワーク I/O
12.3.1 Rustの非同期抽象化
12.3.2 非同期 Redis サーバーの構築
12.4 概要
第 13 章 Rust を使用した Web アプリケーションの構築
13.1 RustのWebアプリケーション
13.2 HTTP通信にハイパーを使用する
13.2.1 ハイパーサーバー側 API による短縮 URL サービスの構築
13.2.2 クライアントとしてのハイパー - URL ショートクライアントの構築
13.2.3 Webフレームワーク
13.3 Actix-Webの基礎知識
13.4 actix-web を使用したブックマーク API の構築
13.5 概要
第14章 RustとWebAssembly
14.1 データの耐久性の重要性
14.2 SQLite
14.3 ポストグレSQL
14.4 r2d2 接続プール
14.5 Postgres とディーゼル ORM
14.6 概要
第15章 RustとWebAssembly
15.1 WebAssmbly とは
15.2 WebAssembly の設計目標
15.3 WebAssembly を始める
15.3.1 オンラインで試す
15.3.2 WebAssembly を生成するメソッド
15.4 RustとWebAssembly
15.4.1 wasm-bindgen
15.4.2 その他の WebAssembly プロジェクト
15.5 概要
第16章 Rustとデスクトップアプリケーション
16.1 GUI開発の概要
16.2 GTKフレームワーク
16.3 gtk-rs を使用してニュース デスクトップ アプリケーションを構築する
16.4 演習
16.5 その他の新たな UI フレームワーク
16.6 概要
第 17 章 デバッグ
17.1 デバッグの概要
17.1.1 デバッガの基本
17.1.2 試運転の前提条件
17.1.3 GDBの構成
17.1.4 プログラム例 — buggie
17.1.5 GDBの基本
17.1.6 Visual Studio Code への GDB の統合
17.2 rr デバッガの概要
17.3 概要