mirror of
https://github.com/alrayyes/wiki.git
synced 2024-11-29 14:36:22 +00:00
109 lines
2.1 KiB
Markdown
109 lines
2.1 KiB
Markdown
|
---
|
|||
|
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);
|
|||
|
}
|
|||
|
```
|