らすとのもじれつ - NF
の続き。自分用のtipsとして、理解してない部分も多いけど取り合えずまとめ。
文字列とか(つづき)
- []でindexアクセスは不可、a番目の文字はs.chars.nth(a).unwrap()で取得
- forループはfo c in s.chars()、indexも同時に欲しい場合はfor (i, c) in s.chars.enumerate()
- 部分文字列の検索、有無だけならcontains(位置も必要ならfind)、以下は「true」が出力
s.contains(t)だとエラーになる。
let s:String = "abcde".to_string(); let t:String = "bcd".to_string(); println!("{}", s.contains(&t));
整数
- 絶対値はa.abs()、以下のコードは「5」が出力
型を指定しないとエラーになるけど、理由は理解してない。指定しなくてもi32だと思うのだけど…
let a:i32 = -5; println!("{}", a.abs());
- 差分取って絶対値を求める場合はa.abs_diff(b)が使える、以下のコードはどっちも「15」が出力
let a:i32 = -5; let b:i32 = 10; println!("{}", a.abs_diff(b)); println!("{}", b.abs_diff(a));
- べき乗はa.pow(b)
- 整数を文字に変換、u8型の変数をas charする。以下のコードは「A」が出力
as char使えるのはu8だけなので、型を指定しないとエラー。ASCIIなので65が大文字A、97が小文字a。
let c:u8 = 65; println!("{}", c as char);
Vec
- 初期化は let v = vec![10, 20, 30]のように。以下のコードは「alloc::vec::Vec
」が出力(typeofは後述)
let v = vec![10, 20, 30]; println!("{}", typeof(v));
- 要素を特定の値で初期化したい場合、例えば3つの0で埋めたいなら let v = vec![0; 3];
Vecの場合は変数を使ってvec![0; n]でも初期化できる(普通の配列は出来ない)
let v = vec![10, 20, 30]; for e in v.iter() { println!("{}", type_of(e));
- 要素検索、有無だけならposition()を使う。以下は「5」の要素を探して削除するコード
if let Some(index) = v.iter().position(|x| *x == 5) { v.remove(index); }
HashMap
- std::collections::HashMapのuse宣言が必要、変数宣言は let map = HashMap::new()
- 要素数はv.len()で取得
- []でindexアクセス可だが、map[&a]のようにする必要がある(後述)
- keyにf32型は使えない(ない理由は理解していない)
- sortはそのままでは出来ないので、Vecに変換してから
let mut v: Vec<(&&str, &i32)> = map.iter().collect(); v.sort_by(|a, b| a.0.cmp(&b.0)); // keyを昇順に並び替え v.sort_by(|a, b| a.1.cmp(&b.1)); // valueを昇順に並び替え v.sort_by(|a, b| b.1.cmp(&a.1)); // valueを降順に並び替え
応用とか
- 型を出力する関数
所有権の問題?で処理の前に呼ぶとエラーになるので注意(理解してない)
fn typeof<T>(_: T) -> String{ let a = std::any::type_name::<T>(); return a.to_string(); }
- for_eachで逐次処理
Vecに含まれる文字の数を数えてHashMapに設定、以下は「{30: 1, 20: 1, 10: 2}」が出力
let v = [10, 10, 20, 30]; let mut map = HashMap::new(); v.iter().for_each(|x|{ let cnt = map.entry(x).or_insert(0); *cnt += 1; }); println!("{:?}", map);
- 畳み込みはfold()、ちゃんと理解してない
以下はVecを0~10で初期化して要素を全て足し込むコード(sumがあるので微妙な例だけど)
let v:Vec<i32> = (1..=10).collect(); println!("{}", v.iter().fold(0, |acc, x| acc + *x));
- C++でいうpairは無いのでtupleを使う
C++でいう「pairのvector」をproconioでやりたい場合、p:[(usize,usize);n],で受け取り、p[i].0のようにアクセス
- itertoolsについてもどっかで追記したい(組み合わせとか)