やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rust自習(連結リストの取得系インタフェース考察)

 getnext。よく考えると所有権ムーブする系としない系がある。

これまで

 取得系メソッドのインタフェースは以下を想定していた。

impl<T> LinkedList<T> {
    pub fn get(&mut self, index: u32) -> &mut T { return &mut self.head.as_mut().unwrap().item; }
    pub fn next(&mut self) -> &mut T { return &mut self.head.as_mut().unwrap().item; }
}

要件

 でも、よく考えたら、以下のような要件があった。

  • 所有権をムーブしたいときと、したくないときがある
  • 全体からある位置にある要素をひとつだけ取得したいときと、ひとつずつすべて取得したいときがある
  • 配列のようにlist[index]という糖衣構文を実装したい(list.as_mut_from_index(index);とかは嫌)
所有権ムーブ 取得対象
する 1個のみ
する すべて(1個ずつ)
しない 1個のみ
しない すべて(1個ずつ)

調査

 以下のようなメソッドが欲しい、のか?

所有権ムーブ 取得対象 メソッド
する 1個のみ next()
する すべて(1個ずつ) into_iter()
しない 1個のみ as_ref_from_index(), as_mut_from_index()
しない すべて(1個ずつ) iter(), iter_mut()

 上から3番目が微妙。他の3つは標準モジュールにトレイトがあったり、それっぽいメソッド名があったりする。でも、上から3番目のやつはlist[0]list[0] = 1みたいな記法でやるほうがスッキリできると思う。演算子のオーバーライトで実装するのだろうか? 調査が大変そうなので後回し。

方針

 std::iter::Iteratorトレイトを実装すれば、into_iter()もついてくるらしい。これで所有権を奪うイテレータは実装完了になる、と思う。

 2番目、iter(), iter_mut()。これらは所有権を奪わずに不変参照・可変参照を返す。

 3番目、next()の参照版。next_ref(), next_mut()みたいなメソッドを持つトレイトは見つけられなかった。

 4番目、get_ref_from_index(i32), get_mut_from_index(i32)みたいな指定した位置にある要素の参照を返すメソッドが欲しい。だが、そんなトレイトは見つからない。これらメソッドは順序をもった配列系の構造には求められると思うのだが。いや、list[0], list[0] = 1のような記法のオーバーライドで代用するのか? それ、どうやってやるの?

結論

 とりあえずstd::iter::Iteratorトレイトのnextを実装しよう。

展望

 それをやれば他のメソッドもついてくるらしい。たとえばinto_iter()。所有権を奪ってイテレータを返すメソッド。イテレータにはfilterなどの極めて有用なメソッドが多数あるっぽい。まだよく知らない。少しずつ調べていこう。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで