【rust】数値と文字のキャストについて
疑問
Q.「手を動かして考えればよくわかる高効率言語Rust書き方・作りかた」というRustの本を読んでたら、シーザー暗号のサンプルにて、文字から数値のキャストにi16を利用し、変換操作のあと、i8にして表示していた。 最初からi8でよいのでは? また、u16やu8ではだめなのか? という疑問がわいた。
A.よく読んだらRustでは文字は4バイト、Cなどでは1バイトと本文に記載があったので、それの影響かも。。。 また、後の確認の結果、result(文字列)に詰めるときはu8でないといけないし、それまでの変換処理では-を使うため符号ありの型を使う必要がありそう。
後学のために自分なりに検証してみる。
検証1 最初からi8でよいのでは?
ソース変更。左は本のソースを写経したものであり、右が一部修正したもの。
↓実行結果
> rustc .\ceasertest.rs; .\ceasertest.exe
> L ORYH BRX. => I LOVE YOU.
上記の変更だと正常に動く。 ただし、11行目のu8をi8にしたところ下記のエラーが出力された。
> rustc .\ceasertest.rs; .\ceasertest.exe
error[E0604]: only `u8` can be cast as `char`, not `i8`
--> .\ceasertest.rs:11:21
|
11 | result.push((code as i8) as char);
| ^^^^^^^^^^^^^^^^^^^^ invalid cast
|
help: try casting from `u8` instead
--> .\ceasertest.rs:11:21
|
11 | result.push((code as i8) as char);
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0604`.
L ORYH BRX. => I LOVE YOU.
「resultがString::new()で初期化(宣言?)した文字の配列(=文字列)のため、変数に格納する際にはchar(文字)にする必要がある。charへの変換はu8じゃないとダメ」というエラーのように見える。 i8とu8あたりの変換は扱っている数値が小さいからか問題なさそう。
検証2 また、u16やu8ではだめなのか?
全部u16バージョン
実行結果
> rustc .\ceasertest.rs; .\ceasertest.exe
error[E0600]: cannot apply unary operator `-` to type `u16`
--> .\ceasertest.rs:18:29
|
18 | let dec = encrypt(&enc, -3);
| ^^ cannot apply unary operator `-`
|
= note: unsigned values cannot be negated
error: aborting due to previous error
For more information about this error, try `rustc --explain E0600`.
L ORYH BRX. => I LOVE YOU.
引数で-を指定しているので、符号なしのu16は型の不一致で怒られているように見える。 まぁそう。
u8も同じ理由で正しくは動かなそう。