72 lines
1.6 KiB
Rust

//! Implementing Deref allows customization of the * operator.
use std::ops::Deref;
// defining our own smart pointer
// for struct MyBox and its implementation
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x: T) -> MyBox<T> {
MyBox(x)
}
}
// treating a type like a reference by implementing the Deref trait
// impl section
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
// This is a tuple with one element inside of a box??
&self.0
}
}
fn hello(name: &str) {
println!("Hello, {name}!");
}
fn main() {
// following the pointer to the value
let x = 5;
let y = &x;
// *y to follow the reference to the value in x.
assert_eq!(5, x);
assert_eq!(5, *y);
// Using Box<T> like a reference
let x = 5;
let y = Box::new(x);
assert_eq!(5, x);
assert_eq!(5, *y);
// defining our own smart pointer
let x = 5;
let y = MyBox::new(x);
assert_eq!(5, x);
assert_eq!(5, *y);
// Implicit deref coercions with functions and methods
// deref coercion converts a reference to a type that implements
// Deref trait into a reference to another type.
let m = MyBox::new(String::from("Rust"));
hello(&m);
// How deref coercion interacts with mutability
//
// Rust does deref coercion when it finds types and
// trait implementations in three cases:
// 1) From &T to &U when `T: Deref<Target=U>`
// 2) From &mut T to &mut U when `T: DerefMut<Target=U>`
// 3) From &mut T to &U when `T: Deref<Target=U>`
//
// Rust will never coerce an immutable reference into a
// mutable reference.
}