大家好,我是梦兽编程。欢迎回来与梦兽编程一起刷Rust的系列。
这是由 Google 的 Android开发团队的分享Rust课程。本课程涵盖了 Rust 的方方面面,从基本语法到泛型和错误处理等高级主题。
该课程的最新版本可以在 google.github.io/comprehensi…
如果你喜欢看梦兽编程的版本可以订阅跟着谷歌安卓团队学Rust订阅最新内容,梦兽编程也期待大家关注我的个人网站。
加入梦兽编程微信群,公众号回复111即可。
面向对象
当我们谈论面向对象编程时,我们关注的是如何组织代码和数据,以及如何使用这些代码和数据。
面向对象编程将数据和操作数据的代码封装在一起,形成一个称为对象的单元。对象可以具有属性(数据)和方法(操作)。通过创建对象,我们可以模拟现实世界中的事物或概念,并通过对象之间的交互来解决问题。
面向对象编程的核心概念包括封装、继承和多态。
面向对象编程的目标是将复杂的问题分解为简单的对象,并通过对象之间的交互来解决问题。它提供了一种组织和管理代码的有效方式,并且可以提高代码的可读性、可维护性和可重用性。
struct
结构体 (struct),Rust 与 golang 语言类似没有提供class关键词。同样提供了struct,但是在rust中通过结构体 (struct) 和 trait(trait)来实现面向对象的特性。
与c++/c不一样的地方是:
Rust引入了所有权系统和借用检查器,以确保内存安全和避免数据竞争。这导致Rust在编写面向对象代码时需要更多的注意事项,例如处理生命周期和借用规则。
封装
struct Circle {
radius: f64,
}
impl Circle {
fn new(radius: f64) -> Self {
Circle { radius }
}
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius * self.radius
}
}
fn main() {
let circle = Circle::new(3.0);
println!("Area of the circle: {}", circle.area());
}
与其他语言一样,rust中的“类”(class)也是拥有方法的功能。只不过rust中需要使用impl再定义一次。你可以这么认为struct定义“类”的属性。impl实现它的方法。这样做的好处是可以开发分离。如果你要在其他语言系统中实现以上代码大概如下:
// java 已经忘得差不多了不要见怪
class CircleAbstract {
float radius = 0;
}
class Circle extends CircleAbstract {
Circle(float radius) {
this.radius = radius;
}
public area() {
return PI * this.radius * this.radius;
}
}
如果你有洁癖需要分开两个文件来写的,在其他语言中估计是需要这样实现。这样对比下来是不是感觉rust会相对简单一点?
继承 & 多态
继承是面向对象的第二特性,它允许一个类(称为子类或派生类)从另一个类(称为父类或基类)继承属性和方法。子类可以从父类继承其所有的非私有成员,包括变量和方法。通过继承,子类可以重用父类的代码,并且可以在其基础上进行扩展或修改。
// 这里使用interface是因为多态
interface Animal {
void makeSound();
}
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
dog.makeSound();
cat.makeSound();
}
}
在java语言中,我们需要使用interface来约束未来class的实现。在rust中只不过把interface改成trait,implements改为for。然后继承的写法上是反过来。
trait Animal {
fn make_sound(&self);
}
struct Dog;
impl Animal for Dog {
fn make_sound(&self) {
println!("Woof!");
}
}
struct Cat;
impl Animal for Cat {
fn make_sound(&self) {
println!("Meow!");
}
}
fn main() {
let dog = Dog;
let cat = Cat;
dog.make_sound();
cat.make_sound();
}
多态的作用/好处
在强制类型语言中,多态显得非常重要。如果你使用js/php。这个再使用的过程中完全可以忽略,因为javascript万物皆可json,php中万物皆可array。但是再强制类型语言中,不同的类型是不能放在一起,为了解决这个问题引入了多态。还是上面的的例子进行改造。
我们先定义两个结构体Dog,Cat。然后分别定义一个trait接口Pet,分别继承Pet接口。Vec这个暂时可以了解,这个可以理解成Java里面的ArrayList那玩意,后面进入高级的时候会详细再介绍。
struct Dog { name: String, age: i8 }
struct Cat { lives: i8 } // No name needed, cats won't respond anyway.
trait Pet {
fn talk(&self) -> String;
}
impl Pet for Dog {
fn talk(&self) -> String { format!("Woof, my name is {}!", self.name) }
}
impl Pet for Cat {
fn talk(&self) -> String { String::from("Miau!") }
}
fn main() {
// 定义一个可变的数组集合
let pets: Vec<Box<dyn Pet>> = vec![
Box::new(Cat { lives: 9 }),
Box::new(Dog { name: String::from("Fido"), age: 5 }),
];
for pet in pets {
println!("Hello, who are you? {}", pet.talk());
}
}
Deriving
在 Rust 中,"Deriving" 是一种自动为结构体或枚举类型实现特定 trait 的机制。通过使用 "derive" 注解,开发人员可以自动为类型实现一些常见的 trait,而不需要手动编写实现代码。
"Deriving" 机制的目的是减少开发人员的重复劳动,使得实现一些常用 trait 的过程更加简单和高效。例如,通过添加 #[derive(Debug)] 注解,Rust 编译器会自动为结构体或枚举类型实现 Debug trait,使得我们可以通过 println! 宏打印出这些类型的调试信息。
除了 Debug trait,Rust 还提供了其他一些可以使用 "derive" 注解自动实现的 trait,如 Clone、Copy、PartialEq、Eq、PartialOrd、Ord 等。这些 trait 在实现某些功能时非常常见,因此通过 "derive" 机制可以大大简化代码编写过程。
需要注意的是,并非所有的 trait 都可以通过 "derive" 机制来自动实现,只有 Rust 标准库中预定义的一些 trait 才支持这种自动实现机制。如果需要实现的 trait 不在预定义的列表中,开发人员仍然需要手动编写实现代码。
#[derive(Debug, Clone, 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);
}
比如我们在这个结构体中添加了Clone,Default的能力。我们的p1对象就拥有了default设置默认值的方法,还有clone的方法。
总结
以上就是Rust面向对象的所有内容啦,当然这些这是让你快速入门。如果你想了解关于它是如何实现,内存机制等等比较深入的东西。建议你去看《Rust圣经》。
- 梦兽编程倔强号
- 梦兽编程知乎
- 梦兽编程bilibili
微信搜索梦兽编程公众号,发送111即可加入交流群与梦兽编程一起交流。
参考资料
[1]
google.github.io/comprehensi…: google.github.io/comprehensi…
[2]
跟着谷歌团队学Rust: rexweb.link/category/te…
[3]
梦兽编程: rexweb.link
本文使用 markdown.com.cn 排版