※2018年6月21更新:Rust 1.26以降(Inclusive rangeを使用)
はじめに
forとか書かなくていいなら書かないほうがよくない??????
もちろん、書いたほうが読みやすいぜ!
みたいなところもあるけど。
でも、例えば1~100の数字に対してすべて2倍するとか、奇数だけ取り出して二乗するとか
fizzbuzzするとかそういうことするだけだったら、ぶっちゃけfor文いらないよね。
以下の例では、Vecを例に使っているけど、スライスも
Iteratorトレイトを実装しているので、まったく同じコードで書ける。
for文を使わずに、奇数を2乗
fn main(){
let n = (0..=20).collect::<Vec<u32>>();
let v = n.iter().filter(|n|(*n)%2==1).map(|n|n*n).collect::<Vec<u32>>();
println!("{:?}",v);
}
ちょースマート
もっとスマートに(追記)
fn main(){
println!("{:?}",(0..=20).filter(|n|(*n)%2==1).map(|n| n * n).collect::<Vec<u32>>());
}
もっともっとスマートに(追の追記)
@tatsuya6502 さんからめっちゃ良いアドバイスをもらったので追記
ありがとうございます
fn main() {
(0..=20)
.filter_map(|n| if n % 2 == 1 { Some(n * n) } else { None })
.for_each(|n| print!("{}, ", n));
println!("");
}
filter_mapで条件と実行内容を合わせて書けるの良いし
for_eachでprintできるから自分で成型する場合もすごく見やすくなった。
めっちゃPythonっぽい。
for文使わずにFizzbuzzする
fn main(){
let n = (0..=20).collect::<Vec<u32>>();
let fb = n.iter().map(fizzbuzz).collect::<Vec<String>>();
println!("{:?}",fb);
}
fn fizzbuzz(n:&u32)->String{
match n{
n if n%3==0&&n%5==0 =>"fizz buzz".to_owned(),
n if n%3==0 =>"fizz".to_owned(),
n if n%5==0 =>"buzz".to_owned(),
n => n.to_string()
}
}
最の高
もっとスマートに(追記)
fn main(){
println!("{:?}",(0..=20).map(fizzbuzz).collect::<Vec<String>>());
}
fn fizzbuzz(n:u32)->String{
match n{
n if n%3==0&&n%5==0 =>"fizz buzz".to_owned(),
n if n%3==0 =>"fizz".to_owned(),
n if n%5==0 =>"buzz".to_owned(),
n => n.to_string()
}
}
もっともっとスマートに(追の追記)
fn main() {
(1..=20).map(fizzbuzz).for_each(|n| print!("{}, ", n));
println!("");
}
fn fizzbuzz(n:u32)->String{
match n{
n if n%15==0 =>"fizz buzz".to_owned(),
n if n%3==0 =>"fizz".to_owned(),
n if n%5==0 =>"buzz".to_owned(),
n => n.to_string()
}
}
どんなコードが実際吐かれるかは書かれてるかは逆アセ見てみればわかるけど
たぶんVecの処理がなくなったからヒープのアロケートとコピーが減ったりで
早くなってるかもしれない
おわりに
Rustはいいぞ。