kuretchi's blog

kuretchi's blog

競技プログラミングなどなど...

ラッパーの参照と参照のラッパー

何かをラップした構造体を作ることがよくある.例えば,何らかの 1 ワードの値 hoge を常に引き回す必要があるとき:

struct Value {}

impl Value {
  fn f0(&self, hoge: usize) {}
  fn f1(&self, hoge: usize, fuga: i32) {}
  // ...
}

こんな構造体を作って,Deref を実装する.

struct WithHoge<T> {
  hoge: usize,
  inner: T,
}

impl<T> Deref for WithHoge<T> {
  type Target = T;

  fn deref(&self) -> &T {
    &self.inner
  }
}

しめしめ.これでさっきの例はこう書けるぞ.

impl WithHoge<Value> {
  fn f0(&self) {}
  fn f1(&self, fuga: i32) {}
  // ...
}

と思いきや,これは適切ではない.正しくはこう.

impl WithHoge<&Value> {
  fn f0(self) {}
  fn f1(self, fuga: i32) {}
  // ...
}