前回のDartの続きで、Rustというもう一つ注目している言語をとりあげます。(いまさら感ありますがなかなか機会がなかったので・・) C言語のようなローレベル言語が持つパフォーマンスの良さと、高い安全性、モダン言語の機能を合わせ持つというとても魅力的なものです。
参考)
スクリプトマガジン vol.64
【翻訳】RustとCSV解析 https://qiita.com/algebroid/items/c456d4ec555ae04c7f92
上記特集の最初のコードにあるreqwestクレートのWebアクセスサンプルにいきなり驚かされました。クレートというのはライブラリパッケージのようなものでこういった環境がコマンド一つですぐに整うところが好みです。
インストール(Mac)
xcode-select –install
https://rustup.rs/ にアクセスしてコマンドを取得
curl –proto ‘=https’ –tlsv1.2 -sSf https://sh.rustup.rs | sh
rustコマンドで確認
rustc -V
rustc 1.51.0 (2fd73fabe 2021-03-23)
rustup update
あとはrustコマンドを使わずビルド、実行ができます。
cargo new mypackagename
cargo build
cargo run
ソースコードは src/main.rs にデフォルトでHello Wolrdを表示するプログラムがあり、これを編集します。
csvフォーマットのデータファイルを編集することを想定して、まず読み込んで表示するプログラムを作成しました。
1 2 3 4 5 6 |
fn main() { let mut rdr = csv::Reader::from_reader(std::io::stdin()); for r in rdr.records() { println!("{:?}", r); } } |
Cargo.toml ファイルの[dependencies]に
csv = “1.1”
と記述するだけで自動的に関連ファイルをダウンロードしてビルドしてくれます。
csvクレートは
https://crates.io/crates/csv
で、使い方を見ることができます。
実行
cargo run < test.csv
csvファイル
abc,def,ghi
111,222,333
111,222,333,444
結果
Ok(StringRecord([“111”, “222”, “333”]))
Err(Error(UnequalLengths { pos: Some(Position { byte: 24, line: 3, record: 2 }), expected_len: 3, len: 4 }))
1行目はヘッダでスキップ、2行目はデータ表示、3行目は列数が多いためランタイムエラーがでました。
動的言語ならありそうな出力(こんなに親切に出してくれないかも)ですが、C言語なら配列が十分に定義されていないのなら危ない処理です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
use std::error::Error; fn main() { if let Err(err) = csv_read() { println!("{}", err); } } fn csv_read() -> Result<(), Box<dyn Error>> { let mut rdr = csv::Reader::from_reader(std::io::stdin()); for r in rdr.records() { let rec = r?; println!("{:?}", rec); } Ok(()) } |
StringRecord([“111”, “222”, “333”])
CSV error: record 2 (line: 3, byte: 24): found record with 4 fields, but the previous record has 3 fields
次は、1行目はヘッダでスキップ、2行目はデータ表示、3行目は列数オーバーでさっきよりさらにわかりやすいエラー表示です。
let rec = r?;
と
Ok(())
というのが特徴的です。
前者は、前回も引用したSwiftのOptionalと同じですね。Cの書き方でNULLポインタを回避する仕組みです。
後者の書き方は馴染みがないのですが(セミコロンなし)、Boxingという仕組みを表すための書き方です。
Rustは特集記事にもCとHaskellを融合させたものとありますが、最近の言語の機能をすべて持っていて、さらに所有権モデルという新しい機能をもあり、押さえておかなくてはいけないと強く思っています。
Haskellも好きな言語で過去に何度か記事をかきました。
http://crossframe.iiv.jp/category/haskell/
https://decode.red/blog/tag/haskell/
http://bitlife.me/archives/tag/haskell
個人的には、コードの品質をコード規約や単体テストで改善しようとすることにくらべたら、難解な言語仕様や文法でもビルド時にデバッグできるのならの方がいいです。(生産性は慣れでカバー) という考えでHaskellも学んだのですが、このRustは十分にわかりやすい言語仕様で安全性もあるということで、後発言語ゆえの優位性を感じます。