Rust で自動でデリファレンスされるやつのメモ2
Rustには->演算子の代わりとなるようなものはありません; その代わり、Rustには、 自動参照および参照外しという機能があります。Rustにおいてメソッド呼び出しは、 この動作が行われる数少ない箇所なのです。
動作方法はこうです: object.something()とメソッドを呼び出すと、 コンパイラはobjectがメソッドのシグニチャと合致するように、自動で&か&mut、*を付与するのです。 要するに、以下のコードは同じものです:
p1.distance(&p2);
(&p1).distance(&p2);
let s = "foo".to_string(); let ss = &s; let sss = &ss; assert_eq!(3, sss.len()); assert_eq!(3, (***sss).len());
今日得た学びとしては、usize 型の + (std::ops::Add) は、usize を返すので、&usize を使ってるときの配列やベクタの添え字(usize が必要となる)でこんな感じになった。
let v: Vec<u32> = vec![11, 22, 33, 44, 55]; let i: usize = 3; let j = &i; assert_eq!(44, v[*j]); // j は &usize 型だから、添え字にできず、* のデリファレンスが要る assert_eq!(55, v[j + 1]); // (*j).add(1) で 新規の usize 型の値が返ってくるのでそれがそのまま添え字になる
手動でのデリファレンスが必要だったり不要だったりした。
Rust で Vector の先頭の要素を取り出したり押し込んだりするときは VecDeque を使う
通常の Vector では push() と pop() しかなくて、いずれも配列の最後の要素に対してしか操作できない。先頭の要素を取り出したり、要素を押し込んだりするためには、std::collections::VecDeque を使うのが良いようだ。
(Ruby の Array#shift とか Array#unshift と同じ動きのやつ)
VecDeque in std::collections - Rust
use std::collections::VecDeque; fn main() { // いつもの Vec let mut v: Vec<i32> = Vec::new(); v.push(1); // 末尾に追加 v.push(2); v.push(3); v.push(4); v.pop(); // 末尾から取得して削除 (Option<T>) assert_eq!(vec![1, 2, 3], v); let mut v2: VecDeque<i32> = VecDeque::new(); v2.push_back(1); // Vec push と同じ v2.push_back(2); v2.push_back(3); v2.push_back(4); v2.pop_front(); // 先頭から取得して削除 (Option<T>) assert_eq!(vec![2, 3, 4], Vec::from(v2.clone())); v2.push_front(1); // 先頭に要素を押し込む v2.pop_back(); // Vec pop と同じ assert_eq!(vec![1, 2, 3], Vec::from(v2.clone())); }
Vector とはメモリの使い方が違うらしく、ソートとかスライスとかを期待通りに取得するためには、その前に make_contiguous() で合体しないといけならしいので注意するというメモ。
Rust のトレイトとかトレイトオブジェクトとかサブトレイトとかジェネリクスのときのトレイトのやつのメモ
いろいろ試したメモ。なんとかぼんやりと理解できてきた。
続きを読む