rust: Rustがんばろう 11日目
2025/04/09
はじめに
勉強し続けていれば急にわかった気持ちになる日がやってくる、そう信じて続ける Rust勉強である。
日常使いするところまで持ってこないとテクニックどうとかよりも記憶から消えてしまうのよね。
C言語だと数年ぶりであっても何とかなっている(たぶん)ので、若い頃の記憶が消えていないだけかもしれない。
組み込み開発だとほぼ C言語しか使わないので、業務歴=C言語歴になる。
他の言語をやるよりもハードウェア関係の方を重視したので、私の今の状況は受け入れざるを得ないのだ。
まあ、それで仕事になっていたのでよかったのだよ、きっと。
ただちょっとした弊害として、長いことやっていない言語で開発するのが怖いという気持ちが出てきてしまう。 ツールによる支援が得られにくいこともあり、C言語を使う人は増える方向にはならなさそうな気がする。
AI によるコードレビューが進化しているので、コードを書いている間の直接の支援はされなかったとしても レビュー機能によって C言語でもメモリリークなんかが静的に見つけられたりすると Rust 使わなくてもいいよ、みたいな時代が来るかもしれない!
などと意味が無いことを考えてないで Rust がんばろう。
9章
Rust は debug ビルドだとデフォルトで異常終了時にスタックトレースが出力される。
golang も出力されていたと思うので最近はそういうものかもしれない。
C言語だとデバッガ使わないと出てこないけど、Linux だと OS もあるしなんか仕込めた気がする。
Binary Hacks(Rebootedじゃない方)に同じことが書いてあったけど著者の一人であった。
Arm だと HardFault とかだっけ。
最近は Nordic のプラットフォームに載っかった作業しかしていないから見かけていないが、あれはつらいものだ。
マッチガード
&
は参照にマッチしてその値を返すref
は値にマッチしてそれへの参照を返す
ここで &
を使うと &Err()
ではないのでマッチしない、ということかな。
最後の Err(error)
を Err(ref error)
にしても問題はなかった。
最初の File::open()
に属する match
では Err(error)
だけど、内側での File::create()
に属する match
では Err(e)
になっているのは何か意味があるのだろうか?
単に外側と内側で区別を付けたかっただけだろうか。
まだこういう細かい違いを気にすべきなのかどうなのかが判断できない。
String::parse()
このコードが気になった。
let home: IpAddr = "127.0.0.1".parse().unwrap();
は変数側の型定義がないとエラーになる。
マッチガードの例だと期待する型 or Err()
であることを利用して match
で判別しているが、
ここは固定文字列だからエラーになる方がおかしいということで IpAddr
をわざと指定しているが
そういうのもありますよという例だ。
気になるのはそこではなく、なんで文字列を .parse().unwrap()
したら IpAddr
型になるのかだ。
String::parse() には IpAddr
とは直接関係がない。
let home = "127.0.0.1".parse::<IpAddr>().unwrap();
という書き方の省略形なのだろうか。
“turbofish” なんて単語はなさそうだが、そういう名前?が付いている。
Trait FromStr を持っている?実装している?ならその型に変換できるようだ。
IpAddr
も一覧に載っている。
これ かな?
まねしてみたが unwrap()
の書き方が判らなかったので unwarp_or()
でごまかした。
use std::str::FromStr;
struct Abc {
s: String
}
struct AbcParseError();
impl FromStr for Abc {
type Err = AbcParseError;
fn from_str(_: &str) -> Result<Self, AbcParseError> {
Ok(Abc { s: "abc".to_string() })
}
}
fn main() {
let home: Abc = "127.0.0.1".parse().unwrap_or(Abc { s: "oops".to_string() });
print!("Hello, World!: {}\n", home.s);
}
unwrap() は正常系のみ
unwrap_or()
を使ったけど、そもそも unwrap()
ってなんだったっけ。
正常というか、Result<_, _>
で match()
で Ok()
になって中身だけ取り出す際、
そういうのを書かずに 1行で済ませられる書き方だ。
「このファイルあるよね、あって当然だよね、なかったら異常で処理できないよね」みたいなときに使うとよろしい。
おわりに
9章は、ちょっと panic!()
使い過ぎなんじゃないの??という気持ちなのだが、
サンプルコードだし、適切な panic!()
を使わないやり方を説明しても
この章の内容にそぐわないだけだし、と考えるとこうなってしまうのだろう。
次だ、次。