method
#[derive(Debug)]
struct Race {
name: String,
laps: Vec<i32>,
}
impl Race {
// No receiver, a static method
//创建一个方法
fn new(name: &str) -> Self {
Self { name: String::from(name), laps: Vec::new() }
}
// Exclusive borrowed read-write access to self
fn add_lap(&mut self, lap: i32) {
self.laps.push(lap);
}
// Shared and read-only borrowed access to self
fn print_laps(&self) {
println!("Recorded {} laps for {}:", self.laps.len(), self.name);
for (idx, lap) in self.laps.iter().enumerate() {
println!("Lap {idx}: {lap} sec");
}
}
// Exclusive ownership of self
fn finish(self) {
let total: i32 = self.laps.iter().sum();
println!("Race {} is finished, total lap time: {}", self.name, total);
}
}
fn main() {
let mut race = Race::new("Monaco Grand Prix");
race.add_lap(70);
race.add_lap(68);
race.print_laps();
race.add_lap(71);
race.print_laps();
race.finish();
// race.add_lap(42);
}
方法是各个语言中都存在的实现方式,在Rust中实现方法通过fn实现,但是Rust的方法有一些特别之处。
- 方法的第一个参数必须为self!!!(必须的一个点,如果第一个参数不是self那么就是一个关联函数了)
- 方法的调用通过.的方式,即race.new();如果是关联函数则通过::的方式,即Race::new()(一开始接触Rust傻傻分不清为什么有的是通过.一些通过::调用);
- 方法的第一个参数为&selt:【代表方法借用对象但是不可修改对象属性】
- 方法的第一个参数为&mut self:【代表方法借用对象可以修改对象的属性】
- 方法的第一个参数为self:【代表方法直接获取对象的所有权,但是不能修改对象,方法执行结束对象将被释放】
- 方法的第一个参数为mut selft:【代表方法直接获取对象的所有权,可以修改对象,方法执行结束对象将被释放】
trait
//创建一个Dog构造函数
struct Dog {
name: String,
age: i8,
}
//创建一个构造函数Cat
struct Cat {
lives: i8,
}
//实现一个特征Pet,实现了两个方法talk和greet
trait Pet {
fn talk(&self) -> String;
fn greet(&self) {
println!("Oh you're a cutie! What's your name? {}", self.talk());
}
}
//为Dog构造函数实现Pet的特征
impl Pet for Dog {
fn talk(&self) -> String {
format!("Woof, my name is {}!", self.name)
}
}
//为Cat构造函数实现Pet的特征
impl Pet for Cat {
fn talk(&self) -> String {
String::from("Miau!")
}
}
fn main() {
let captain_floof = Cat { lives: 9 };
let fido = Dog { name: String::from("Fido"), age: 5 };
captain_floof.greet();
fido.greet();
}
trait在Rust中叫做特征,说直白点就是接口(也搞不懂为啥不用接口,其它的语言都是用接口来实现通用的抽象方法,Rust自创了一套)。就是类似Java中的Interface。作用都是一样的抽象通用的方法,用户只要关心接口即可,不需要关心具体的实现。
derive
#[derive(Debug, Clone, Default)]//实现Debug、Clone、Default三个特征,则Rust会自动为Player构造函数实现三个特征的方法,类似Java中Interface接口的default方法
struct Player {
name: String,
strength: u8,
hit_points: u8,
}
fn main() {
let p1 = Player::default(); // Default trait adds `default` constructor.
let mut p2 = p1.clone(); // Clone trait adds `clone` method.
p2.name = String::from("EldurScrollz");
// Debug trait adds support for printing with `{:?}`.
println!("{:?} vs. {:?}", p1, p2);
}
derive在Rust中的角色是工具型,即会自动为构造函数实现特征的默认方法,类似Java中Interface接口中default的方法。
trait Clone {
fn clone() {
//todo clone的实现
}
}
#[derive(Clone)]
struct Player {
}
//以下代码是上面的代码的具体实现
impl Clone for Player {
//该代码是derive的具体实现,Rust通过derive自动实现了
}