Rust自習(連結リスト8)
std::ops::Indexトレイトのindex
メソッドをオーバーライドした。
成果物
std::ops::Indexトレイトのindex
メソッド
list[index]
みたいな表記で不変参照を得たい。そのためにはstd::ops::Indexトレイトのindex
メソッドをオーバーライドすればいいと判明。
トレイトは以下のように定義されている。
pub trait Index<Idx> where Idx: ?Sized { type Output: ?Sized; fn index(&'a self, index: Idx) -> &'a Self::Output; }
オーバーライド
これを任意の構造体に実装するときは以下のように書く。
struct MyStruct; impl std::ops::Index<usize> for MyStruct { type Output = Option<i32>; fn index(&self, index: usize) -> &Self::Output { &None } } fn main() { let s = MyStruct{}; println!("{:?}", s[0]) }
$ rustc main.rs $ ./main None
コード
今回はジェネリック型を交えて書くので以下。
impl<T> std::ops::Index<usize> for LinkedList<T> { type Output = T; fn index(&self, index: usize) -> &Self::Output { fn get_ptr_from_idx<T>(ptr: &Option<Box<Node<T>>>, index: usize, count: usize) -> &Option<Box<Node<T>>> { if count < index { if ptr.is_some() { return get_ptr_from_idx(&ptr.as_ref().unwrap().next, index, count+1); } else { return ptr; } } else { return ptr; } } if let Some(ref _n) = get_ptr_from_idx(&self.head, index, 0) { return &(_n.item) } else { panic!("Out of index. index値が大きすぎます。index: {:?}", index); } } }
テストコード
#[test] #[should_panic(expected = "Out of index. index値が大きすぎます。index: 0")] fn LinkedList_index_out_of_index_0() { let mut list: LinkedList<i32> = LinkedList::new(); list[0]; } #[test] #[should_panic(expected = "Out of index. index値が大きすぎます。index: 1")] fn LinkedList_index_out_of_index_1() { let mut list: LinkedList<i32> = LinkedList::new(); list.push(10); list[1]; } #[test] fn LinkedList_index_1() { let mut list: LinkedList<i32> = LinkedList::new(); list.push(10); assert_eq!(list[0], 10); } #[test] fn LinkedList_index_3() { let mut list: LinkedList<i32> = LinkedList::new(); list.push(10); list.push(20); list.push(30); assert_eq!(list[0], 10); assert_eq!(list[1], 20); assert_eq!(list[2], 30); }
所感
ついに[index]
演算子のオーバーライドができた! この調子で代入できるIndexMut
も実装しよう。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
- rustc 1.34.2 (6c2484dc3 2019-05-13)
- cargo 1.34.0 (6789d8a0a 2019-04-01)
$ uname -a Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux
前回まで
- Rust学習まとめ(ドキュメント)
- Rust自習(じゃんけんゲーム1)
- Rust自習(双方向リスト1)
- Rust自習(単方向リスト1)
- Rust自習(単方向リスト2)
- Rust自習(単方向リスト3)
- Rust自習(単方向リスト4)
- Rust自習(単方向リスト5)
- Rust自習(単方向リスト6)
- Rust自習(単方向リスト7)
- Rust自習(リストのインタフェースを考える)
- Rust自習(連結リスト1)
- Rust自習(連結リスト2)
- Rust自習(連結リスト3)
- Rust自習(連結リスト4)
- Rust自習(連結リストの取得系インタフェース考察)
- Rust自習(連結リスト5)
- Rust自習(連結リストの取得系インタフェース考察2)
- Rust自習(連結リスト6)
- Rust自習(連結リスト7)