3

It's possible to borrow a Vec<u32> into either a &Vec<u32> or a &[u32]. I thought this was thanks to either the AsRef or Borrow traits. However, I was unable to implement such borrowing on my own custom type. Am I barking up the wrong tree here?

use std::borrow::Borrow;

struct MyArray([u32; 5]);

impl MyArray {
    fn new() -> MyArray {
        MyArray([42; 5])
    }
}

impl AsRef<[u32]> for MyArray {
    fn as_ref(&self) -> &[u32] {
        &self.0
    }
}

impl Borrow<[u32]> for MyArray {
    fn borrow(&self) -> &[u32] {
        &self.0
    }
}

fn main() {
    let ma = MyArray::new();
    let _: &[u32] = &ma; // compilation failure
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Michael Snoyman
  • 31,100
  • 3
  • 48
  • 77

1 Answers1

6

You are looking for std::ops::Deref:

In addition to being used for explicit dereferencing operations with the (unary) * operator in immutable contexts, Deref is also used implicitly by the compiler in many circumstances. This mechanism is called 'Deref coercion'. In mutable contexts, DerefMut is used.

Modified code:

use std::ops::Deref;

struct MyArray([u32; 5]);

impl MyArray {
    fn new() -> MyArray {
        MyArray([42; 5])
    }
}

impl Deref for MyArray {
    type Target = [u32];

    fn deref(&self) -> &[u32] {
        &self.0
    }
}

fn main() {
    let ma = MyArray::new();
    let _: &[u32] = &ma;
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
udoprog
  • 1,825
  • 14
  • 14
  • Related: [Is it considered a bad practice to implement Deref for newtypes?](https://stackoverflow.com/q/45086595/155423). – Shepmaster Nov 11 '18 at 16:51