赞
踩
基础的部分直接类比C++的泛型,给出代码实例 :
struct Point<T> { x: T, y: T } impl<T> Point<T> { fn foo(&self) -> &Point<T> { &self } } // 模板的特化,只针对f32类型的数据 impl Point<f32> { fn add(&self, other: Point<f32>) ->f32 { self.x + other.x + self.y + other.y } }
注意上述代码中,impl
后面的T
泛型是必须的,这告诉编译器,在Point<T>
的T
是一个泛型标记。
结构体方法中定义的泛型可以和结构体中声明的不一致,比如:
impl<T, U> Point<T, U> {
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
这就相当于Java的interface
,先给出一个代码实例:
pub trait Action { // 定义trait fn run(&self); fn get_name(&self) -> String; fn jump(&self) { // 默认方法 println!("{} cannot jump", self.get_name()); } } pub struct Car { name: String, } pub struct Duck { name: String, } // 为Car结构体实现Action接口 impl Action for Car { fn run(&self) { println!("car runs"); } fn get_name(&self) -> String { self.name.clone() } } // 为Duck结构体实现Action接口 impl Action for Duck { fn run(&self) { println!("duck runs"); } fn get_name(&self) -> String { self.name.clone() } fn jump(&self) { println!("{} jumps", self.get_name()); } } fn main() { let car = Car { name: String::from("Ferrari"), }; let duck = Duck { name: String::from("Foo"), }; car.run(); duck.run(); println!("car name: {}, duck name: {}", car.get_name(), duck.get_name()); car.jump(); duck.jump(); }
代码输出:
car runs
duck runs
car name: Ferrari, duck name: Foo
Ferrari cannot jump
Foo jumps
只要实现了trait
的所有方法,那么就可以作为trait
类型的参数使用,trait
中默认实现的方法也包含在内,代码实例:
pub trait Action { fn run(&self); fn jump(&self); } struct Duck { name: String, } impl Duck { // 实现自己的方法 fn get_name(&self) -> String { self.name.clone() } } impl Action for Duck { // 实现trait的方法 fn run(&self) { println!("{} runs", self.get_name()); } fn jump(&self) { println!("{} jumps", self.get_name()); } } // 绝大多数是借用的方式 fn foo(ac: &impl Action) { ac.run(); ac.jump(); } fn main() { let duck = Duck { name: String::from("foo"), }; foo(&duck); }
trait bound
的概念。我们有泛型函数的概念,但是可以使用trait
限制泛型的类型是实现了trait
某些方法的泛型,代码实例:
pub trait Action { fn run(&self); fn jump(&self); } pub trait Wealth { fn get_money(&self) -> f32; } struct Duck { name: String, money: f32, } impl Duck { fn get_name(&self) -> String { self.name.clone() } } impl Action for Duck { fn run(&self) { println!("{} runs", self.get_name()); } fn jump(&self) { println!("{} jumps", self.get_name()); } } impl Wealth for Duck { fn get_money(&self) -> f32 { self.money } } // 参数必须实现了Action和Wealth这两个trait fn foo<T: Action + Wealth>(ac: &T) { ac.run(); ac.jump(); print!("It has {} dollars", ac.get_money()); } fn main() { let duck = Duck { name: String::from("foo"), money: 8898.4 }; foo(&duck); }
如果参数的trait
类型过多的话,可以使用where
语法,具体的代码实例:
pub trait Action { fn run(&self); } pub trait Wealth { fn pay(&self); } pub trait Fame { fn show(&self); } struct Duck { money: f32, } struct Human { money: f32, fame: String, } impl Action for Duck { fn run(&self) { println!("duck runs"); } } impl Wealth for Duck { fn pay(&self) { println!("duck cost $10"); } } impl Wealth for Human { fn pay(&self) { println!("human has $10"); } } impl Fame for Human { fn show(&self) { println!("human has fame"); } } // 利用where进行组合 fn foo<T, U>(man: &T, duck: &U) where T: Wealth + Fame, U: Action + Wealth { man.pay(); man.show(); duck.run(); duck.pay(); } fn main() { let duck = Duck { money: 10.0, }; let man = Human { money: 10.0, fame: "Dr".to_string(), }; foo(&man, &duck); }
trait也可以作为返回类型,代码实例:
pub trait Action { fn run(&self); } struct Duck { name: String, } impl Action for Duck { fn run(&self) { println!("duck is running"); } } // 返回trait类型 fn foo(name: String) -> impl Action { Duck { name, } } fn main() { let duck = foo(String::from("foo")); duck.run(); }
rust本身没有继承语法,现在利用trait
的方式实现继承:
trait Page { fn set_page(&self, p: i32) { println!("Page Default: 1"); } } trait PerPage { fn set_per_page(&self, p: i32) { println!("Per Page Default: 10"); } } struct MyPaginate { page: i32 } impl Page for MyPaginate {} impl PerPage for MyPaginate {} trait Paginate: Page + PerPage { // 这里是继承的语法,Pagninate继承了Page和PerPage fn set_skip_page(&self, num: i32) { println!("Skip page {:?}", num); } } impl<T: Page + PerPage> Paginate for T {} // 这里的意思是为所有实现Page和PerPage的行为实现Paginate特有的方法 fn main() { let my_paginate = MyPaginate { page: 10 }; my_paginate.set_page(10); my_paginate.set_per_page(20); my_paginate.set_skip_page(10); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。