C++工程师的Rust迁移之路(1)- 起步

Rust应该是最近最热门的几个语言之一。

它既有C++的零成本抽象能力;又跟C语言一样,贴近底层,内存布局一览无遗;但同时又没有这些语言的历史负担,具有现代语言非常优秀的表达和抽象能力;最重要的是,它从语言层面上实现了内存与线程安全。

本系列文章,是专门针对对Rust感兴趣的C++工程师的,主要介绍了完成相同的任务在C++和Rust中的异同。关于Rust设计上的优秀和特点,就不在本系列文章中集中解释了,大家可以在每一个对比细节中慢慢感受,看它是不是直击你的痛点。

Hello, World

C++

#include <iostream>
int main(int argc, char* argc[]) {
    std::cout<<"Hello, world"<<std::endl;
    return 0;
}

Rust

fn main() {
    println!("Hello, world");
}

从第一个例子可以看到Rust的语法习惯对于从类C语言转过来的开发者还是很友好的。代码块仍然是大括号包围的,语句仍然是分号结尾的,当然主函数还是叫做main。

变量

C++

int number = 0;
const int const_number = -100;
number = const_number;

Rust

let mut number = 0;
let const_number = -100;
number = const_number;

这里可以看到,在Rust中,变量默认是不可变的,除非加了mut关键字。

基本数据类型

C++

bool boolean = true;
std::uint8_t u8 = 0;
std::int16_t i16 = 0;
std::size_t size = 0;
float real = 0;
double precise_real = 0;
char character = 'A';
const char* c_string = "Hello, world";
std::string string = "Hello, world";

Rust

let boolean: bool = true;
let uint8: u8 = 0;
let int16: i16 = 0;
let size: usize = 0;
let real: f32 = 0;
let precise_real: f64 = 0;
let character: char = '😊';
let str_ref: &str = "Hello, world 🚀";
let string: String = "Hello, world 🍎".to_owned();

这里可以看到Rust的数据类型系统跟C++还是有很大的不同:

  • 数值类型都是定长的类型,这样开发者在开发的时候可以明确的知道它在内存中占用的大小,以及它们的取值范围,避免犯错;
  • 字符类型是4字节的Unicode字面量(Scalar Value),可以完整的涵盖Unicode的所有字符集,所以可以看到我可以把emoji 😊赋值给一个字符变量;
  • 和C++的const char*类似的是&str类型,str类型实际上是无法在程序中定义的(因为它的长度是动态的),你只能使用它的引用类型(&str);它指向一个以UTF8编码存储的字符串(这样比较节约内存,又能完整覆盖unicode编码),但操作的时候,又是以char类型进行操作的,避免用户手工处理UTF8的过程中出现错误。(说句题外话,Rust的字符串库是所有语言中,对Unicode规范支持的最完善的,没有之一)。
  • Rust中的String类型实际上是std::string::String类型,它与C++的std::string类似,内部存储了字符串的拷贝,因此提供了操作字符串的内容,比如修改字符串等等。同样的,它内部的存储模式是UTF8,但操作的时候是以character为单位来操作的。

延伸阅读

黄珏珅:C++工程师的Rust迁移之路(2)- 类与结构体zhuanlan.zhihu.com图标

编辑于 2019-07-29