世の中には、Prashant N Mhatreさんによる、15 Exercises for learning new programming languagesというものがあるようです。邦訳すると、新しいプログラミング言語を学ぶための15のエクササイズ。この記事ではこれを解いていきます。
Rustに挑戦してみることにしました
最近注目度の高いRustにちょうど挑戦したかったので、このエクササイズにRustでチャレンジします。
第一回
Display series of numbers (1,2,3,4, 5....etc) in an infinite loop. The program should quit if someone hits a specific key (Say ESCAPE key).
解答例
さっそく私の解答から出しますと、こんな感じになりました。今回はxをエスケープ用のキーとしています。
extern crate getch;
use getch::Getch;
use std::sync::mpsc::channel;
use std::thread::spawn;
use std::result::Result;
use std::io::Error;
fn main() {
println!("If you want to stop, please press x key!");
let (sender, receiver) = channel();
spawn(move || {
loop{
let g: Result<Getch, Error> = Getch::new();
let key: Result<u8, Error> = Getch::getch(&g.ok().unwrap());
const KEY_X: u8 = 120;
let input_key = key.ok().unwrap();
if input_key == KEY_X {
sender.send(true).unwrap();
break;
}
}
});
let mut i = 0;
loop {
println!("{}", i);
i = i + 1;
if receiver.try_recv().ok() != None {
break;
}
}
}
解説
インポート文
extern crate getch;
use getch::Getch;
use std::sync::mpsc::channel;
use std::thread::spawn;
use std::result::Result;
use std::io::Error;
長い。
もう少しスマートな書き方があるのではないかと調べているけれど見つからず、と言った感じです。
今回は、keyが押されたかどうかを知るためにGetchを利用しました。
チャネル定義
println!("If you want to stop, please press x key!");
let (sender, receiver) = channel();
一文目は普通のprintlnです。止めたかったらxボタン押してねと。
二文目は、スレッド間で通信するためのチャネルを定義しています。結構雑な理解なので私は説明できる水準ではありません。
ループ部分1:キー入力を受け取る
spawn(move || {
loop{
let g: Result<Getch, Error> = Getch::new();
let key: Result<u8, Error> = Getch::getch(&g.ok().unwrap());
const KEY_X: u8 = 120;
let input_key = key.ok().unwrap();
if input_key == KEY_X {
sender.send(true).unwrap();
break;
}
}
});
spawnやらmoveやらでスレッドを立てています。
Getchの処理は非常に苦労したのですが、とりあえずこれで動きます。(ベストプラクティスからは程遠いです)
Rustでは、Result型というものがあり、これがなかなか面倒くさいです。
条件を満たしたら、sender.sendでtrueを送信
ループ2
let mut i = 0;
loop {
println!("{}", i);
i = i + 1;
if receiver.try_recv().ok() != None {
break;
}
}
普通にループしているだけですね。先ほどのsenderから送られた信号を受信したらループをbreakします。
まとめ
- Rustはとても楽しい
- Result型難しい
- インポート文を簡潔にする方法がよくわからない。
以上!