はじめに
ちょっと前から気になっていたプログラミング言語「Rust」を覚えようと思い、
とにかく手を動かそうと思って、oreillyの「Rustの練習帳」に手を付けてみた。
この本は、読めばRustの知識がつく・読むとRustが書ける、というようなものではなく、
お題、ひな形や最低限の条件が書いてあって、それに沿って自分でRustを書いて覚えるという本である。
そのため、本に書いてあることをただ読んで、書いてあることをそのまま書くだけでは、
Rustのプログラムが完成しないようになっている。
(一応完成例があるので、それを先に読めば完成するが...)
この本でRustを練習していったなかで、自分で見つけたエラー解決方法や
自分が実施したオリジナル要素を、備忘録として、この記事に残すこととした。
本記事の目的
Rustの楽しさを広める
本記事に限らず、自分がRustの記事を書く時の目的は
「Rustの楽しさを広めて、Rustエンジニアを増やす」
である。
本記事の目的
で、この記事を読んだ人が
- Rustの練習帳で躓いたことが解決する
- Rustで躓いたことを解決し、Rustに対するモヤモヤが減る
- Rustに触れやすくなる
- Rustが楽しくなる
ことを目的とする。
(さすがに楽しくはならないかも)
本記事の内容
Rustの練習帳での練習において、解決に苦労したエラーだったり、練習帳にはないオリジナルなことを記載する。
これらの内容を見ることで、スムーズにRust練習ができることを目指す。
なおこの記事は、Rustの練習帳を進めながら執筆しているため、
内容は予告なしに追加・変更することがあることをご注意ください。
つまづいたこと
練習帳通りに進めていたら、エラーや予想通りに動かない事態が多々ある。
その中で、特に解決が困難だったことを記録する。
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というファイルに書くと書いてあった。
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つを試してみた。
- OneDriveなどにRustコードを入れる
- 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のドキュメントを読んだところ、
- 今はバージョンが2.33ではなく、4.5になっている。
- 破壊的変更が多いのか、使用できないクレートや関数が多々ある。
ことにカルチャーショックを覚えた。
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の公式ドキュメントを参照。
↓↓↓↓↓