C++类和Rust的结构体之间做一个对比,顺便介绍Rust中的核心概念Trait。
类vs结构体
C++
class Rectangle {
public:
Rectangle(float width, float height)
: width_(width), height_(height)
{}
public:
float area() const {
return width_ * height_;
}
void resize(width, height) {
width_ = width;
height_ = height;
}
private:
float width_, height_;
};
Rust
struct Rectangle {
width: f32,
height: f32
}
impl Rectangle {
pub fn new(width: f32, height: f32) -> Rectangle {
Rectangle {
width: width,
height: height
}
}
pub fn area(&self) -> f32 {
self.width * self.height
}
pub fn resize(&mut self, width: f32, height: f32) {
self.width = width;
self.height = height;
}
}
对于C++开发者来说,有一件事情是众所周知的:struct和class本质上是一样的,唯一的区别就是struct的成员默认是public的,而class的成员默认是private的。
而对于Rust来说,它没有class的概念,只有struct的概念。而Rust中的struct的成员默认都是private的,除非加上pub关键词做修饰。
从语法上来说,可以看到Rust跟C++有一个很大的不同。在C++里面,往往我们的方法声明(对于模版类来说,甚至定义也是如此)是包含在class body这个大的语句块内的,而且对于顺序没有明确的要求。而在Rust里面,结构体的声明仅包含了它内部的数据结构,相关的实现是放在额外的impl语句块中的。这个变化看似稀松平常,但内含着巨大的好处,特别是类的逻辑比较复杂的时候。作为C++程序员,我们一定碰到过那种在一个类的头上和一个类的尾端,甚至是某些函数之间都声明了成员变量的情况。这就引入了一个风险,就是当你修改代码的时候,有可能会忘记给其中的某些变量赋值,这非常危险。而在Rust中,由于结构体的成员变量是与函数分开,并且集中在一起的,就大大降低了出现这种情况的概率。
在C++中,我们写一个类时,第一个要做的事情,就是定义它的构造函数;而反观Rust,它是没有构造函数这个概念的。上述代码中的new函数,如果对比C++的概念的话,相当于Rectangle类的一个静态方法,它的名字叫做new,接受2个f32类型的参数,返回值是一个Rectangle对象。这里有三点需要注意的:
我们再接着看area和resize两个方法,可以看到它们的第一个参数分别是&self, 和&mut self。这里其实也有两点需要注意的:
Playground
Rust语言的官网提供了一个Playground工具,可以供大家在无需安装Rust环境的前提下,试用Rust。
本文中的例子我也发布到了Rust Playground上,链接如下:
Rust Playgroundplay.rust-lang.org
欢迎大家使用。