2024-05-06 20:40:05 +00:00
|
|
|
|
---
|
2024-10-30 17:34:11 +00:00
|
|
|
|
date: 2020-09-29
|
2024-05-06 20:40:05 +00:00
|
|
|
|
id: d2d028c8-733f-4cdb-b096-89cf8b3de961
|
|
|
|
|
title: Deref Trait
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
# Introduction
|
|
|
|
|
|
|
|
|
|
Implementing the `Deref` trait allows you to customize the behavior of
|
|
|
|
|
the *dereference operator*, \* (as opposed to the multiplication or glob
|
|
|
|
|
operator). By implementing `Deref` in such a way that a smart pointer
|
|
|
|
|
can be treated like a regular reference, you can write code that
|
|
|
|
|
operates on references and use that code with smart pointers too:
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
fn main() {
|
|
|
|
|
let x = 5;
|
|
|
|
|
let y = &x;
|
|
|
|
|
|
|
|
|
|
assert_eq!(5, x);
|
|
|
|
|
assert_eq!(5, *y);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# Box
|
|
|
|
|
|
|
|
|
|
A [Box\<T\>](20200929135609-box_t) can also be used:
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
fn main() {
|
|
|
|
|
let x = 5;
|
|
|
|
|
let y = Box::new(x);
|
|
|
|
|
|
|
|
|
|
assert_eq!(5, x);
|
|
|
|
|
assert_eq!(5, *y);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# Deref Trait
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
use std::ops::Deref;
|
|
|
|
|
|
|
|
|
|
impl<T> Deref for MyBox<T> {
|
|
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
|
|
fn deref(&self) -> &T {
|
|
|
|
|
&self.0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct MyBox<T>(T);
|
|
|
|
|
|
|
|
|
|
impl<T> MyBox<T> {
|
|
|
|
|
fn new(x: T) -> MyBox<T> {
|
|
|
|
|
MyBox(x)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let x = 5;
|
|
|
|
|
let y = MyBox::new(x);
|
|
|
|
|
|
|
|
|
|
assert_eq!(5, x);
|
|
|
|
|
assert_eq!(5, *y);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# Deref Coercion
|
|
|
|
|
|
|
|
|
|
*Deref coercion* is a convenience that Rust performs on arguments to
|
|
|
|
|
functions and methods. Deref coercion works only on types that implement
|
|
|
|
|
the Deref trait. Deref coercion converts such a type into a reference to
|
|
|
|
|
another type. For example, deref coercion can convert `&String` to
|
|
|
|
|
`&str` because `String` implements the `Deref` trait such that it
|
|
|
|
|
returns `str`. Deref coercion happens automatically when we pass a
|
|
|
|
|
reference to a particular type’s value as an argument to a function or
|
|
|
|
|
method that doesn’t match the parameter type in the function or method
|
|
|
|
|
definition. A sequence of calls to the `deref` method converts the type
|
|
|
|
|
we provided into the type the parameter needs.
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
use std::ops::Deref;
|
|
|
|
|
|
|
|
|
|
impl<T> Deref for MyBox<T> {
|
|
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
|
|
fn deref(&self) -> &T {
|
|
|
|
|
&self.0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct MyBox<T>(T);
|
|
|
|
|
|
|
|
|
|
impl<T> MyBox<T> {
|
|
|
|
|
fn new(x: T) -> MyBox<T> {
|
|
|
|
|
MyBox(x)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn hello(name: &str) {
|
|
|
|
|
println!("Hello, {}!", name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let m = MyBox::new(String::from("Rust"));
|
|
|
|
|
hello(&m);
|
|
|
|
|
}
|
|
|
|
|
```
|