1
2

Rustの練習帳で練習してみた

Posted at

はじめに

ちょっと前から気になっていたプログラミング言語「Rust」を覚えようと思い、
とにかく手を動かそうと思って、oreillyの「Rustの練習帳」に手を付けてみた。

この本は、読めばRustの知識がつく・読むとRustが書ける、というようなものではなく、
お題、ひな形や最低限の条件が書いてあって、それに沿って自分でRustを書いて覚えるという本である。

そのため、本に書いてあることをただ読んで、書いてあることをそのまま書くだけでは、
Rustのプログラムが完成しないようになっている。
(一応完成例があるので、それを先に読めば完成するが...)

この本でRustを練習していったなかで、自分で見つけたエラー解決方法や
自分が実施したオリジナル要素を、備忘録として、この記事に残すこととした。

本記事の目的

Rustの楽しさを広める

本記事に限らず、自分がRustの記事を書く時の目的は
「Rustの楽しさを広めて、Rustエンジニアを増やす」
である。

本記事の目的

で、この記事を読んだ人が

  • Rustの練習帳で躓いたことが解決する
  • Rustで躓いたことを解決し、Rustに対するモヤモヤが減る
  • Rustに触れやすくなる
  • Rustが楽しくなる
    ことを目的とする。
    (さすがに楽しくはならないかも)

本記事の内容

Rustの練習帳での練習において、解決に苦労したエラーだったり、練習帳にはないオリジナルなことを記載する。
これらの内容を見ることで、スムーズにRust練習ができることを目指す。

なおこの記事は、Rustの練習帳を進めながら執筆しているため、
内容は予告なしに追加・変更することがあることをご注意ください。

つまづいたこと

練習帳通りに進めていたら、エラーや予想通りに動かない事態が多々ある。
その中で、特に解決が困難だったことを記録する。

main.rs から 自クレート内のモジュールを読み込みできない

main.rs
fn main() {
    if let Err(e) = project1::get_args().and_then(project1::run()) {
        eprintln!("{}", e);
        std::process::exit(1);
    }
}

この本では、main.rsはプログラムを実行する際のエントリポイントであり、
基本的にはこの作りにするといったような事が書いてあった。

で、実際の動作である、get_args()とrun()は、
src/lib.csというファイルに書くと書いてあった。

lib.rs
pub fn run(struct: Struct) -> Result<()> {
    println!("{:#?}", struct);
    Ok(())
}

pub fn get_args() -> Result<Struct> {
    let matches: ArgMatches = App::new("command")
        .version("0.1.0")
        .author("Ken")
        .about("Rust command")
        .arg(
            Arg::with_name("files")
            .value_name("FILE")
            ...// 省略
        )
        .arg(
            ...// 省略
        )
        .get_matches();

    Ok(Struct {
        // 省略
    })
}

こんな感じで、libs.rsというファイルを作って、
中に実際の処理を実装した。

で、cargo run をしたところエラー。

use of undeclared crate or module project1

srcフォルダの中にファイルを作って、その中に実装したはずのなのに...
と原因を調べていたら、実装ファイル名がlibs.rs だったのが問題。
どうやらuseなしで自クレートのモジュールを使用する場合は、
必ずlib.rsというファイル名にするらしい。

(参考: ファイル分割によるクレート分割、モジュール分割、パッケージ分割)

オリジナルなこと

AWSで "いつでもどこでもRustの練習"

自分のようなスタバ好きは、家でも外でもRustの練習をしたくなる。
しかしRustの練習帳は、ローカルPCでの練習を想定している。
そのため常に同じPCを使用しないと、作業途中のコードなどが引き継げない。

ということで、以下の2つを試してみた。

  1. OneDriveなどにRustコードを入れる
  2. AWS にRust用インスタンスを作る

1.でやってみたところ、buildするたびに大量のファイル更新と
更新メッセージボックスが頻繁に出てきて、目障りとなってしまった。

2.であれば、最初からLinux環境を作ってそのまま動かすことができるので、
いつでもどこでもやりやすいと思い、AWSのEC2にRust環境を構築した。
(Rustの練習帳はLinuxでの動作が紹介されている。)

どのような環境を作ったかは、時間があれば記載する予定。

  • 無料枠で使える最低限のEC2インスタンスを作る
  • その中にRust環境を作る
  • VSCodeでSSHを出来るようにする
  • VSCodeでRust用EC2にSSH接続して使用する

clap V4 の利用

練習帳では、CLIを作成するために、Rustのclapクレートを使用している。
ただし、紹介されているclapのクレートが2.33と古いバージョンである。

練習していくなかで、なかなかとっかかりづらいところがあった。
それはclapで使用されている名前類がわかりづらいこと。
clapでのコマンドライン作成は何度もするのだが、
いつも何を書けばいいかわからなくて、前のコードを見て、関数などをコピーしている。

自分がわかりづらいと感じたclapの名前類↓

// clapを使用する際のuse
// Appはコマンドラインを作るためのクレート
// ArgはAppで使用する引数
use clap::{App, Arg} // AppってCLI以外も指すのかな?

// コマンドラインを新規作成する関数
let matches: ArgMatches = App::with_name("command") // command という名前...with?

他にもいくつかあるが、clapの名前が直感と異なるので、
これをしたいとき、何と入力すればよいかがすぐ出てこなかった。

で、何を使えばいいか調べるため、clapのドキュメントを読んだところ、

  1. 今はバージョンが2.33ではなく、4.5になっている。
  2. 破壊的変更が多いのか、使用できないクレートや関数が多々ある。

ことにカルチャーショックを覚えた。
V4のドキュメントを見ると、今は幾分わかりやすくなっていた。

そんなことで、練習帳には載っていない、V4でclapを使用する際の
主な変更点を残すことにした。

主な2.33→4.5の変更点

2.33 4.5 備考
clap::App clap::Command Commandの方がCLIっぽい
Arg::with_name Arg::new newの方が作る感じがする
ArgMatch::values_of_lossy ArgMatch::get_many get_manyの方が文字数少ない
take_values(false) num_args(0) 引数ないのを引数ゼロと表す
multiple num_args(1..) 引数1個以上と表す

練習していく中で、見つけたものを随時追加予定。

4.5の方が、直感的でわかりやすい名前になっていたり、
面白い表現になっている。

もっと知りたい方は、clapの公式ドキュメントを参照。
↓↓↓↓↓

(随時追加予定)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2