提交 a0d703d5 编写于 作者: 梦境迷离's avatar 梦境迷离

rust traits

上级 2f21e21f
...@@ -10,10 +10,12 @@ use crate::functions::*; ...@@ -10,10 +10,12 @@ use crate::functions::*;
use crate::generics::*; use crate::generics::*;
use crate::modules::*; use crate::modules::*;
use crate::primitives::*; use crate::primitives::*;
use crate::traits::*;
use crate::types::*; use crate::types::*;
use crate::variable_bindings::*; use crate::variable_bindings::*;
pub mod formatted_print; pub mod formatted_print;
pub mod traits;
pub mod generics; pub mod generics;
pub mod modules; pub mod modules;
pub mod functions; pub mod functions;
...@@ -37,4 +39,5 @@ fn main() { ...@@ -37,4 +39,5 @@ fn main() {
closures(); closures();
modules(); modules();
generics(); generics();
traits::traits();
} }
///特质
pub fn traits() {
struct Sheep { naked: bool, name: &'static str }
impl Sheep {
fn is_naked(&self) -> bool {
self.naked
}
fn shear(&mut self) {
if self.is_naked() {
//实现者方法可以使用实现者的trait方法
println!("{} is already naked...", self.name());
} else {
println!("{} gets a haircut!", self.name);
self.naked = true;
}
}
}
//特质是为未知类型定义的方法的集合:self。他们可以访问以相同特质声明的其他方法。
trait Animal {
//静态方法,self是具体实现者的类型
fn new(name: &'static str) -> Self;
//实例方法
fn name(&self) -> &'static str;
fn noise(&self) -> &'static str;
//特质可以提供默认方法实现
fn talk(&self) {
println!("{} says {}", self.name(), self.noise());
}
}
// 为`Sheep`实现Animal特质
impl Animal for Sheep {
//self的类型是`Sheep`
fn new(name: &'static str) -> Sheep {
Sheep { name: name, naked: false }
}
fn name(&self) -> &'static str {
self.name
}
fn noise(&self) -> &'static str {
if self.is_naked() {
"baaaaah?"
} else {
"baaaaah!"
}
}
//覆盖特质中默认的方法实现
fn talk(&self) {
println!("{} pauses briefly... {}", self.name, self.noise());
}
}
//在这种情况下,必须使用类型注释
let mut dolly: Sheep = Animal::new("Dolly");
// TODO ^ Try removing the type annotations.
dolly.talk();
dolly.shear();
dolly.talk();
//
derive();
return_dyn();
operator_overload();
drop_();
iterators();
impl_trait();
closure_trait();
clone();
supertraits();
overlapping_traits();
}
fn derive() {
//比较特质: Eq, PartialEq, Ord, PartialOrd.
//拷贝特质(深拷贝), to create T from &T via a copy.
//复制特质 相对于move而言, to give a type 'copy semantics' instead of 'move semantics'.
//可hash, to compute a hash from &T.
//默认, to create an empty instance of a data type.
//调试, to format a value using the {:?} formatter.
// `Centimeters`, a tuple struct that can be compared
#[derive(PartialEq, PartialOrd)]
struct Centimeters(f64);
//运行以调试模式打印 {:?}
#[derive(Debug)]
struct Inches(i32);
impl Inches {
fn to_centimeters(&self) -> Centimeters {
let &Inches(inches) = self;
Centimeters(inches as f64 * 2.54)
}
}
#[derive(PartialEq, Debug)]
struct Seconds(i32);
let _one_second = Seconds(1);
println!("One second looks like: {:?}", _one_second);
let _this_is_true = (_one_second == _one_second);
let foot = Inches(12);
println!("One foot equals {:?}", foot);
let meter = Centimeters(100.0);
let cmp =
if foot.to_centimeters() < meter {
"smaller"
} else {
"bigger"
};
println!("One foot is {} than one meter.", cmp);
}
fn return_dyn() {
//返回实现了某一特质的类型的实例
struct Sheep {}
struct Cow {}
trait Animal {
//实例方法
fn noise(&self) -> &'static str;
}
// 为`Sheep`实现Animal特质
impl Animal for Sheep {
fn noise(&self) -> &'static str {
"baaaaah!"
}
}
// 为`Cow`实现Animal特质
impl Animal for Cow {
fn noise(&self) -> &'static str {
"moooooo!"
}
}
//返回一些实现Animal的结构,但是在编译时我们不知道是哪个结构
fn random_animal(random_number: f64) -> Box<dyn Animal> {
if random_number < 0.5 {
Box::new(Sheep {})
} else {
Box::new(Cow {})
}
}
let random_number = 0.234;
let animal = random_animal(random_number);
println!("You've randomly chosen an animal, and it says {}", animal.noise());
}
fn operator_overload() {
//运算符重载
use std::ops;
struct Foo;
struct Bar;
#[derive(Debug)]
struct FooBar;
#[derive(Debug)]
struct BarFoo;
//为Foo类型实现Add特质,以支持add操作
impl ops::Add<Bar> for Foo {
type Output = FooBar;
fn add(self, _rhs: Bar) -> FooBar {
println!("> Foo.add(Bar) was called");
FooBar
}
}
//为Bar类型实现Add特质,以支持add操作
impl ops::Add<Foo> for Bar {
type Output = BarFoo;
fn add(self, _rhs: Foo) -> BarFoo {
println!("> Bar.add(Foo) was called");
BarFoo
}
}
println!("Foo + Bar = {:?}", Foo + Bar);
println!("Bar + Foo = {:?}", Bar + Foo);
}
fn drop_() {
//对象超出范围时自动调用
struct Droppable {
name: &'static str,
}
//为Droppable类型实现Drop特质
impl Drop for Droppable {
fn drop(&mut self) {
println!("> Dropping {}", self.name);
}
}
let _a = Droppable { name: "a" };
// block A
{
let _b = Droppable { name: "b" };
// block B
{
let _c = Droppable { name: "c" };
let _d = Droppable { name: "d" };
println!("Exiting block B");
}
println!("Just exited block B");
println!("Exiting block A");
}
println!("Just exited block A");
drop(_a);
println!("end of the main function");
}
fn iterators() {
//在数组或向量上迭代
struct Fibonacci {
curr: u32,
next: u32,
}
//为Fibonacci类型实现迭代器特质
impl Iterator for Fibonacci {
type Item = u32;
//只需要实现一个next方法
fn next(&mut self) -> Option<u32> {
let new_next = self.curr + self.next;
self.curr = self.next;
self.next = new_next;
//斐波那契没有终点,所以next不会返回None
Some(self.curr)
}
}
//返回一个斐波那契序列生成器
fn fibonacci() -> Fibonacci {
Fibonacci { curr: 0, next: 1 }
}
// `0..3` = 0,1,2
let mut sequence = 0..3;
println!("Four consecutive `next` calls on 0..3");
println!("> {:?}", sequence.next());
println!("> {:?}", sequence.next());
println!("> {:?}", sequence.next());
println!("> {:?}", sequence.next());
println!("Iterate through 0..3 using `for`");
for i in 0..3 {
println!("> {}", i);
}
//拿前4个
println!("The first four terms of the Fibonacci sequence are: ");
for i in fibonacci().take(4) {
println!("> {}", i);
}
//跳过前4个,再拿4个
println!("The next four terms of the Fibonacci sequence are: ");
for i in fibonacci().skip(4).take(4) {
println!("> {}", i);
}
let array = [1u32, 3, 3, 7];
println!("Iterate the following array {:?}", &array);
for i in array.iter() {
println!("> {}", i);
}
}
fn impl_trait() {
//返回 trait类型
use std::iter;
use std::vec::IntoIter;
//组合vec
fn combine_vecs_explicit_return_type(v: Vec<i32>, u: Vec<i32>) -> iter::Cycle<iter::Chain<IntoIter<i32>, IntoIter<i32>>> {
v.into_iter().chain(u.into_iter()).cycle()
}
//简化返回类型
fn combine_vecs(v: Vec<i32>, u: Vec<i32>) -> impl Iterator<Item=i32> {
v.into_iter().chain(u.into_iter()).cycle()
}
let v1 = vec![1, 2, 3];
let v2 = vec![4, 5];
let mut v3 = combine_vecs(v1, v2);
assert_eq!(Some(1), v3.next());
assert_eq!(Some(2), v3.next());
assert_eq!(Some(3), v3.next());
assert_eq!(Some(4), v3.next());
assert_eq!(Some(5), v3.next());
println!("all done");
}
fn closure_trait() {
fn make_adder_function(y: i32) -> impl Fn(i32) -> i32 {
let closure = move |x: i32| { x + y };
closure
}
let plus_one = make_adder_function(1);
assert_eq!(plus_one(2), 3);
fn double_positives<'a>(numbers: &'a Vec<i32>) -> impl Iterator<Item=i32> + 'a {
numbers.iter().filter(|x| x > &&0).map(|x| x * 2)
}
}
fn clone() {
//单元结构体
#[derive(Debug, Clone, Copy)]
struct Nil;
//元祖结构体
#[derive(Clone, Debug)]
struct Pair(Box<i32>, Box<i32>);
let nil = Nil;
let copied_nil = nil;
println!("original: {:?}", nil);
println!("copy: {:?}", copied_nil);
let pair = Pair(Box::new(1), Box::new(2));
println!("original: {:?}", pair);
let moved_pair = pair;
println!("copy: {:?}", moved_pair);
//println!("original: {:?}", pair);
let cloned_pair = moved_pair.clone();
drop(moved_pair);
//println!("copy: {:?}", moved_pair);
println!("clone: {:?}", cloned_pair);
}
fn supertraits() {
trait Person {
fn name(&self) -> String;
}
// Student 是 Person
// 实现 Student 也需要实现 Person.
trait Student: Person {
fn university(&self) -> String;
}
trait Programmer {
fn fav_language(&self) -> String;
}
// 实现CompSciStudent需要同时实现Programmer Student
// CompSciStudent既是Programmer也是Student
trait CompSciStudent: Programmer + Student {
fn git_username(&self) -> String;
}
fn comp_sci_student_greeting(student: &dyn CompSciStudent) -> String {
format!(
"My name is {} and I attend {}. My Git username is {}",
student.name(),
student.university(),
student.git_username()
)
}
}
fn overlapping_traits() {
//消除多个歧义的方法
trait UsernameWidget {
fn get(&self) -> String;
}
trait AgeWidget {
fn get(&self) -> u8;
}
struct Form {
username: String,
age: u8,
}
impl UsernameWidget for Form {
fn get(&self) -> String {
self.username.clone()
}
}
impl AgeWidget for Form {
fn get(&self) -> u8 {
self.age
}
}
//Form 实现了UsernameWidget和AgeWidget,两个特质均有方法get
let form = Form {
username: "rustacean".to_owned(),
age: 28,
};
//不可以这样,编译出错:multiple `get` found
// println!("{}", form.get());
let username = <Form as UsernameWidget>::get(&form);
assert_eq!("rustacean".to_owned(), username);
let age = <Form as AgeWidget>::get(&form);
assert_eq!(28, age);
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册