プロジェクト概要
このプロジェクトでは、ユーザーの入力を受け取り、それに基づいてタスクを管理するシンプルな「To-Doリスト」を構築します。このTo-Doリストは、ユーザーがタスクを追加、一覧表示、削除できる機能を備えた、簡単なコマンドラインアプリケーションです。Rustの基本的なデータ構造や関数、エラーハンドリングなどを効果的に使うことで、実際に役立つプログラムを作成します。
10.1 設計とプロジェクトの準備
10.1.1 必要な機能の洗い出し
To-Doリストアプリケーションに必要な機能は次のとおりです。
- タスクの追加: ユーザーが新しいタスクを入力し、リストに追加できる。
- タスクの表示: すべてのタスクを一覧表示できる。
- タスクの削除: 指定したタスクをリストから削除できる。
- アプリケーションの終了: ユーザーがプログラムを終了できる。
10.1.2 プロジェクトの設定
- Cargoプロジェクトの作成: 新しいプロジェクトフォルダを作成し、Cargoで初期化します。
cargo new todo_list cd todo_list
- src/main.rs: メインのコードはこのファイルに記述していきます。
10.1.3 初期設定
このプログラムでは標準入力からのユーザーの指示を取得するためにstd::io
クレートを使用し、タスクの管理にはVec<String>
を用います。以下がその初期コードです。
use std::io;
fn main() {
println!("To-Doリストアプリへようこそ!");
}
10.2 基本機能の実装
10.2.1 メインループの作成
アプリケーションはユーザーからの指示を待ち、入力に基づいて適切なアクションを実行します。これをメインループで実現します。
fn main() {
println!("To-Doリストアプリへようこそ!");
println!("コマンド: 'add', 'list', 'remove', 'exit' で操作してください。");
loop {
// ユーザー入力を受け取る
let mut input = String::new();
io::stdin().read_line(&mut input).expect("入力エラー");
// コマンドの処理
let command = input.trim();
match command {
"add" => add_task(),
"list" => list_tasks(),
"remove" => remove_task(),
"exit" => {
println!("アプリケーションを終了します。");
break;
}
_ => println!("無効なコマンドです。再入力してください。"),
}
}
}
ここで、loop
文によりユーザー入力を待ち続け、適切なコマンドが入力されると対応する関数が実行されます。
10.2.2 タスクを格納するデータ構造
タスクを格納するためにVec<String>
型の変数を使います。タスクをmain
関数の中で管理するため、main
のスコープに持たせることにします。
let mut tasks: Vec<String> = Vec::new();
10.3 タスク追加機能の実装
ユーザーからタスク内容を入力してもらい、それをtasks
リストに追加するadd_task
関数を実装します。
fn add_task(tasks: &mut Vec<String>) {
println!("追加するタスクを入力してください:");
let mut task = String::new();
io::stdin().read_line(&mut task).expect("入力エラー");
tasks.push(task.trim().to_string());
println!("タスクが追加されました。");
}
ポイント
&mut Vec<String>
という参照で受け取ることで、リストに新しいタスクを追加可能にしています。trim()
で余分な空白を取り除き、無駄なスペースを省きます。
10.4 タスク一覧表示機能の実装
次に、すべてのタスクを表示する関数list_tasks
を作成します。
fn list_tasks(tasks: &Vec<String>) {
if tasks.is_empty() {
println!("タスクはありません。");
} else {
println!("現在のタスク:");
for (i, task) in tasks.iter().enumerate() {
println!("{}: {}", i + 1, task);
}
}
}
ポイント
iter().enumerate()
を使用し、インデックス番号とタスク内容を同時に表示。is_empty()
を使ってタスクがない場合のエラーメッセージも出力しています。
10.5 タスク削除機能の実装
特定のタスクをリストから削除するremove_task
関数を追加します。
fn remove_task(tasks: &mut Vec<String>) {
println!("削除するタスクの番号を入力してください:");
let mut index_str = String::new();
io::stdin().read_line(&mut index_str).expect("入力エラー");
match index_str.trim().parse::<usize>() {
Ok(index) if index > 0 && index <= tasks.len() => {
tasks.remove(index - 1);
println!("タスクが削除されました。");
}
_ => println!("無効な番号です。"),
}
}
ポイント
parse::<usize>()
を使って、入力文字列を数値に変換。- 無効なインデックスの処理も
match
式で対応。
10.6 コードの改善とデバッグのポイント
- 冗長なコードの整理
- コマンドの受付と処理を
main
関数で一つにまとめるのではなく、サブ関数で分離することでコードが読みやすくなり、拡張しやすくなります。
- コマンドの受付と処理を
- ユーザー入力のバリデーション
- 各関数でユーザー入力を必ず検証し、エラーメッセージを出力します。これによりユーザーエラーを未然に防ぎます。
- エラーハンドリングの追加
- 入力に問題があった場合の処理も行い、ユーザーが操作を継続しやすいようにしました。
10.7 完成コード
最終的な完成コードは以下の通りです。
use std::io;
fn main() {
println!("To-Doリストアプリへようこそ!");
println!("コマンド: 'add', 'list', 'remove', 'exit' で操作してください。");
let mut tasks: Vec<String> = Vec::new();
loop {
let mut input = String::new();
io::stdin().read_line(&mut input).expect("入力エラー");
match input.trim() {
"add" => add_task(&mut tasks),
"list" => list_tasks(&tasks),
"remove" => remove_task(&mut tasks),
"exit" => {
println!("アプリケーションを終了します。");
break;
}
_ => println!("無効なコマンドです。再入力してください。"),
}
}
}
fn add_task(tasks: &mut Vec<String>) {
println!("追加するタスクを入力してください:");
let mut task = String::new();
io::stdin().read_line(&mut task).expect("入力エラー");
tasks.push(task.trim().to_string());
println!("タスクが追加されました。");
}
fn list_tasks(tasks: &Vec<String>) {
if tasks.is_empty() {
println!("タスクはありません。");
} else {
println!("現在のタスク:");
for (i, task) in tasks.iter().enumerate() {
println!("{}: {}", i + 1, task);
}
}
}
fn remove_task(tasks: &mut Vec<String>) {
println!("削除するタスクの番号を入力してください:");
let mut index_str = String::new();
io::stdin().read_line(&mut index_str).expect("入力エラー");
match index_str.trim().parse::<usize>() {
Ok(index) if index > 0 && index <= tasks.len() => {
tasks.remove(index - 1);
println!("タスクが削除されました。");
}
_ => println!("無効な番号です。"),
}
}
この章では、Rustの基本的な構文を活用した実用的なアプリケーションの構築方法と、ユーザー入力やエラーハンドリングの実装、そしてコードの改善ポイントを学びました。この経験により、実践的なRustのスキルがさらに身についたことでしょう。
初心者におすすめ!プログラミングスクールのススメ
未経験でも気軽に!サブスク型プログラミングスクール【Freeks】
プログラミングを始めたいと思っているそこのあなた、独学よりもプログラミングスクールが断然おすすめです!理由は簡単、続けやすさです。
独学の挫折率、驚きの87.5%!
独学でプログラミングを続けるのは、実はかなりハードルが高いんです。データによると、なんと87.5%もの学習者が途中で挫折しているとか。一方、各プログラミングスクールが公表しているデータによると、受講生の約95%が最後までやり抜いているとのこと。数字を見れば一目瞭然、プログラミングスクールの方が圧倒的に続けやすいんです。
有料と無料、スクールの違いは?
プログラミングスクールには有料と無料のタイプがありますが、その違いは次の通りです:
- 受講条件が異なる
- 学べるスキルやカリキュラム内容が異なる
- 就職や転職のサポート内容が異なる
どちらが自分に合っているか、よく考えて選ぶのが大事です。
サブスク型プログラミングスクール『FREEKS(フリークス)』に注目!
プログラミング初心者でも学びやすいと評判の『FREEKS』、その特徴は以下の通り:
- 未経験者向けのわかりやすいカリキュラム
- 経験豊富なエンジニアのサポート
- オンラインで自分のペースで学習可能
なんと、月会費のみで全カリキュラムが受け放題!Java、PHP、HTML/CSS、JavaScriptなど、多彩なプログラミング言語が学べるんです。しかも、AIが質問に自動で答えてくれるシステムも導入済み。
終了後は副業もサポート!
カリキュラムを終了した後には、Freeks経由で未経験者でも取り組める副業案件の受注が可能。実務を通じてスキルを磨き、市場価値の高いエンジニアへの道が開けます。
独学で悩むくらいなら、まずはプログラミングスクールをチェックしてみるのもアリかもしれませんよ!
↓ ↓ こちらをクリック ↓ ↓