72 lines
1.6 KiB
Rust
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.
|
|
}
|