Utility Trait is The grap bag of traits which have enough impact while writing idiomatic(관용적인) code. Utility trait can broadly categorized into three groups.
- Language extension traits
- Marker traits
- Public vocabulary
When a value's owner goes away, we say that rust Drop
s the value. The Vec
implements Drop
the each of its elements and then freeing the heap-allocated buffer they occupied. That's why String don't need to implement Drop
. If variable's value gets moved elsewhere, causing the variables to be unitialized when it goes out of scope, then Rust will not automatically drop the value.
#[derive(Debug)]
struct Human{
name: String
}
impl Drop for Human{
fn drop(&mut self) {
println!("{:?} Droped!", self.name);
}
}
fn main() {
let me = Human{
name: "jollidah".into()
};
println!("print struct {:?}", me);
}
// print struct Human { name: "jollidah" }
// "jollidah" Droped!
If type implements Drop
, it can't implements Copy
.
sized type
have the same size in memeory. Almost all types in rust are sized. For example, Vec owns a heap-allocated buffer whose size can vary. But Vec<T> itself is a pointer to the buffer, its capacity, length, so Vec<T> is a sized type. And String
is unsized
type compare contrary to &str
type.
Clone
is a for types that can make copies of themselves. The clone method construct an independent copy of self and return it. But, RC<T> and ARC<T> are exceptions: clone increases reference count and hands you a new pointer. clone_from()
copies resource and move that into *self. When Overwriting heap-allocated resouce, clone_from
often optimize the implements.
Almost all types of rust moves value when assign. But the types which implement Copy
trait don't move their value, they assign the copied value. You can ask Rust to derive with #[dervie(Copy)]
.
You can specify how to dereferencing operators like *
and .
works. If context assigns or borrows mutable reference, Rust uses DerefMut trait; otherwise, read-only access is enough, and it uses Deref.deref and derefmut function take a &self reference and return &Self::Target
reference. Target should be something that Self contains, owns, or refer to: for Box<Complex> the target type is Complex. Sometime Rust corerce Deref and DerefMut, and they are called deref coercions
. You couldn't write out your own function, but It's quiet convenient.
The default function returns fresh value of type Self. String's implementation is straightforward:
impl Default for String {
fn default() -> String {
String::new()
}
}
Rust doesn't implicitly implement Default
for struct. If all field of struct implements Default for struct types, you can implement Default for the struct automatically by using #[derive(Default)]
.
AsRef and AsMut operates like reference. But you can customize the reference's reutrn.
trait AsRef<T: ?Sized> {
fn as_ref(&self) -> &T;
}
trait AsMut<T: ?Sized> {
fn as_mut(&mut self) -> &mut T;
}
From and Into trait convert value from one data type to another. Given appropriate From
implementations, Rust automatically offer corresponding Into implements. ? operator also uses From and Into to convert specific error types to general ones we needed.
We don't know how convertion should behave and that's why we need TryFrom and TryInto. TryFrom and TryInto return Result<>
, so we can choose how to handle the exception case.
pub trait TryFrom<T>: Sized {
type Error;
fn try_from(value: T) -> Result<Self, Self::Error>;
}
A generalization of Clone to borrowed data. Clone
works only for going from &T
to T
. The ToOwned
trait Clone construct owned data from any borrow of given type.
pub trait ToOwned {
type Owned: Borrow<Self>;
// Required method
fn to_owned(&self) -> Self::Owned;
// Provided method
fn clone_into(&self, target: &mut Self::Owned) { ... }
}