书:Rust for Rustaceans
as_
, to_
, into_
规范 用以特定类型转换名称前缀 | 内存代价 | 所有权 |
---|---|---|
as_ | 无代价 | borrowed -> borrowed |
to_ | 代价昂贵 | borrowed -> borrowed borrowed -> owned (非 Copy 类型) owned -> owned (Copy 类型) |
into_ | 视情况而定 | owned -> owned (非 Copy 类型) |
{:?}
打印任何类型Rust 的 trait 系统坚持 孤儿原则 :大致说的是, 每个 impl
块必须
所以,定义新类型的 crates 应该尽早实现所有合适的、常见的 traits 。
(相关资料图)
std
中可给类型实现的、最重要的、常见的 traits 有:
Copy
Clone
Eq
PartialEq
Ord
PartialOrd
Hash
Debug
Display
Default
给类型实现 Default
trait 和空的 new
构造函数是常见和有必要的。new
是 Rust 中常规的构造函数,所以不使用参数来构造基本的类型时, new
对使用者来说就理应存在。default
方法功能上与 new
方法一致,所以也应当存在。
#[derive(Debug)]
,通常是最佳实现方式fmt::Formatter
提供的各种 debug_xxx 辅助方法手动实现debug_struct
debug_tuple
debug_list
debug_set
debug_map
例子一
use std::fmt::Debug;#[derive(Debug)]struct Pair { a: T, b: T,}fn main() { let pair = Pair {a: 5, b: 10}; println!("Pair: {:?}", pair); // i32 实现了 Debug Trait 故可以打印出来}
例子二
use std::fmt::Debug;struct Person { name: String,}#[derive(Debug)]struct Pair { a: T, b: T,}fn main() { let pair = Pair { a: Person { name: "Dave".to_string() }, b: Person { name: "Nick".to_string() }, }; println!("Pair: {:?}", pair); // 报错 `Person` doesn"t implement `Debug` Person 没有实现 Debug Trait}
例子三
use std::fmt;struct Pair { a: T, b: T,}impl fmt::Debug for Pair { fn fmt(&self, f: &mut fmt::Formatter<"_>) -> fmt::Result { f.debug_struct("Pair").field("a", &self.a).field("b", &self.b).finish() }}fn main() { let pair = Pair { a: 5, b: 10 }; println!("Pair: {:?}", pair);}
例子四
#[derive(Debug)]struct MyBox(*mut u8);unsafe impl Send for MyBox {}use std::rc::Rc;fn main() { let mb = MyBox(Box::into_raw(Box::new(42))); let x = Rc::new(42); std::thread::spawn(move || { println!("{:?}", x); // error: `Rc` cannot be sent between threads safely }); //std::thread::spawn(move || { // println!("{:?}", mb); // mb 实现了 Send Trait //});}
例子五
use std::cell::RefCell;use std::sync::Arc;fn main() { let x = Arc::new(RefCell::new(42)); std::thread::spawn(move || { let mut x = x.borrow_mut(); // error: `RefCell` cannot be shared between threads safely *x += 1; });}
例子六
#[derive(Debug, Clone)]struct Person { name: String, age: u32,}impl Person { fn new(name: String, age: u32) -> Person { Person { name, age } }}fn main() { let person1 = Person::new("Alice".to_owned(), 25); let person2 = person1.clone(); println!("Person 1: {:?}", person1); println!("Person 2: {:?}", person2);}
例子七
#[derive(Default)]struct Point { x: i32, y: i32,}fn main() { let point = Point::default(); // 提供默认的初始值 println!("Point: ({}, {})", point.x, point.y); // Point: (0, 0)}
例子八
#[derive(Debug, PartialEq)]struct Point { x: i32, y: i32,}fn main() { let point1 = Point { x: 1, y: 2 }; let point2 = Point { x: 1, y: 2 }; let point3 = Point { x: 3, y: 4 }; println!("point1 == point2: {}", point1 == point2); println!("point1 == point3: {}", point1 == point3);}
std::collection
的集合类型进行去重的类型例子九
use std::collections::BTreeMap;#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]struct Person { name: String, age: u32,}fn main() { let mut ages = BTreeMap::new(); let person1 = Person { name: "Alice".to_owned(), age: 25, }; let person2 = Person { name: "Bob".to_owned(), age: 30, }; let person3 = Person { name: "Charlie".to_owned(), age: 20, }; ages.insert(person1.clone(), "Alice"s age"); ages.insert(person2.clone(), "Bob"s age"); ages.insert(person3.clone(), "Charlie"s age"); for (person, description) in &ages { println!("{}: {} - {:?}", person.name, person.age, description); }}
例子十
use std::collections::HashSet;use std::hash::{Hash, Hasher};#[derive(Debug, PartialEq, Eq, Clone)]struct Person { name: String, age: u32,}impl Hash for Person { fn hash(&self, state: &mut H) { self.name.hash(state); self.age.hash(state); }}fn main() { let mut persons = HashSet::new(); let person1 = Person { name: "Alice".to_owned(), age: 25, }; let person2 = Person { name: "Bob".to_owned(), age: 30, }; let person3 = Person { name: "Charlie".to_owned(), age: 20, }; persons.insert(person1.clone()); persons.insert(person2.clone()); persons.insert(person3.clone()); println!("Persons: {:?}", persons);}
例子十一
// Eq// 反身性(Reflexivity):对于任何对象 x,x == x 必须为真。// 对称性(Symmetry):对于任何对象 x 和 y,如果 x == y 为真,则 y == x 也必须为真。// 传递性(Transitivity):对于任何对象 x、y 和 z,如果 x == y 为真,并且 y == z 为真,则 x == z 也必须为真。// Ord// 自反性(Reflexivity):对于任何对象 x,x <= x 和 x >= x 必须为真。// 反对称性(Antisymmetry):对于任何对象 x 和 y,如果 x <= y 和 y <= x 都为真,则 x == y 必须为真。// 传递性(Transitivity):对于任何对象 x、y 和 z,如果 x <= y 和 y <= z 都为真,则 x <= z 必须为真。fn main() { }
serde_derive
(crate)提供了机制,可以覆盖单个字段或枚举变体的序列化例子十二:你写的库
[dependencies]serde = { version = "1.0", optional = true}[features]serde = ["serde"]
例子十三:别人用的时候
[dependencies]mylib = { version = "0.1", features = ["serde"] }
例子十四
#[derive(Debug, Copy, Clone)]struct Point { x: i32, y: i32,}fn main() { let point1 = Point { x: 10, y: 20 }; let point2 = point1; // 这里发生复制,而不是移动 println!("point1: {:?}", point1); println!("point2: {:?}", point2);}
fn foo(t: T)
&T where T: Trait
&mut T where T: Trait
Box where T: Trait
T: Deref
,可以在 T 类型值上直接调用类型 U 的方法例子十五
use std::ops::Deref;struct MyVec(Vec);impl Deref for MyVec { type Target = Vec; fn deref(&self) -> &Self::Target { &self.0 }}fn main() { let my_vec = MyVec(vec![1, 2, 3, 4, 5]); println!("Length: {}", my_vec.len()); println!("First element: {}", my_vec[0]);}
From
和 Into
,以便用户可轻松地添加或移除包装。例子十六
use std::ops::Deref;struct Wrapper(String);impl Deref for Wrapper { type Target = String; fn deref(&self) -> *Self::Target { &self.0 }}impl AsRef for Wrapper { fn as_ref(&self) -> &str { &self.0 }}impl From for Wrapper { fn from(s: String) -> Self { Wrapper(s) }}impl From for String { fn from(wrapper: Wrapper) -> Self { wrapper.0 }}fn main() { let wrapper = Wrapper::from("Hello".to_string()); // 使用 . 运算符调用内部字符串类型的方法 println!("Length: {}", wrapper.len()); // 使用 as_ref 方法将 Wrapper 转换为 &str 类型 let inner_ref: &str = wrapper.as_ref(); println!("Inner: {}", inner_ref); // 将 Wrapper 转换为内部类型 String let inner_string: String = wrapper.into(); println!("Inner String: {}", inner_string);}
HashSet
,Borrow 允许调用者提供 &str
或 &String
。Borrow
、&T
和 &mut T
提供了通用实现例子十七
use std::borrow::Borrow;fn print_length(string: S)whereS: Borrow,{ println!("Length: {}", string.borrow().len());}fn main() { let str1: &str = "Hello"; let string1: String = String::from("World"); print_length(str1); print_length(string1);}
免责声明:本文不构成任何商业建议,投资有风险,选择需谨慎!本站发布的图文一切为分享交流,传播正能量,此文不保证数据的准确性,内容仅供参考
关键词: