rust语言特点及基础配置
Rust是mozilla推出的一款系统级的编程语言,其两大特点在于零开销抽象和安全性。
在大学里时候,就开始注意到rust语言的动态了。
当时,我在啃一本大块头的C++书籍《C++ Primer》,觉得rust处处针对到了C++的痛处。
学习rust,即能够让你用不输于C++的特性编程,而又不用花费太多的精力在语法的各种特例和各种细枝末节的坑中。
优秀的程序员都需要掌握多语言以学习不同的思维方式。对于系统级语言,rust是相当优秀的,
最近趁着有点时间,得好好学习一下这门我垂诞已久的语言了。
<!--more-->
rust的特点
在大学里时候,就开始注意到rust语言的动态了。当时,我在啃一本大块头的C++书籍《C++ Primer》。
C++是相当难学,其中是因为其因为历史遗留原因及与C的兼容性,导致语法正交性、统一性差,
要学习的语法点及要避免的踩坑点相当之多,乃至于一部分同学都是“C++从入门到放弃”了。(我也是)
而剩下一部分说用C++的同学,实际上是C with class,不敢用太高级的特性,怕hold不住。。。
拥有作为系统级语言C++的优势
类似于C++,Rust的定位是一款系统级语言,因此,它具有C++作为系统级语言的所有特点:
- 零开销抽象 。抽象不会引入额外的开销,编译器会编译出非常高性能的机器代码。
- 没有gc 。系统级语言需要应用于实时性要求高的场景,不能用gc。也用于编写底层基础设施,没有必要用gc。
- 内存模型没有高度封装。和C++一样,你即可以将对象分配到栈上,也可以将对象分配到堆上。
对于系统级的语言需要这些的细粒度控制力,而不是像java之类的高级语言,只需要知道引用的概念即可使用java了,无需关心内存分配问题。
拥有更强的静态类型检查和现代语言特性
除此之外,除了拥有C++优点外,它还有:
- 语法干净正交,没有C++那么繁琐。
- 安全性。Rust语法引入所有权和生命期概念,在编译期就能检查出一部分内存管理错误,
这是rust的一个杀手锏的特性。 - 现代语言特性。语言特性吸收了现代语言的大量优秀特性,支持多范式。
没有C++的历史遗留问题
从我了解到的信息来看,还有以下几种对标C++的特点,对于一个初学者,目前感受还不是很大:
- 现代化的模块系统,比C++那种古老的继承C语言的方式(利用#include预编译和编译单元的概念)要好用很多。
- 更好用的泛型。比C++的模板更容易使用。
rust开发环境的搭建
第一步,安装rust工具链:
官方网站推荐的方式是:
curl https://sh.rustup.rs -sSf | sh
这样,会将rust工具链安装到~/.cargo/bin
目录下,包括rustc、cargo 及 rustup。
推荐爬墙下载,我选择proxychains:
proxychains curl https://sh.rustup.rs -sSf > tmp.sh sh tmp.sh
第二步:安装IDE。
我推荐使用jetbrains推出的rust插件。找一个jetbrains的IDE安装就行了。
作为一名java码农,我选择idea。与把大象放入冰箱一样轻松,只需简单三步:
- 打开intellij idea。
- Settings -> Plugins,安装rust插件。
- Settings -> Languages & Framworks -> Rust 配置标准库路径和其他选项。
好了,新建一个项目,你会发现多了一个rust选择项。
作为初学者,不要花费过多精力在工具链上,首先应该快速搞起一个环境,然后上手语法写几个demo。
第一个rust程序
作为第一个rust程序,首先来个选择排序压压惊:
fn selection_sort(nums: &mut Vec<i32>) { for i in 0.. nums.len() { let mut min = i; for j in i.. nums.len() { if nums[j] < nums[min] { min = j; } } nums.swap(i, min); } }
rust中的语法不是C系语法,所以熟悉rust的语法需要多多编写代码练习。上面代码涉及到的语法有:
- 首先,使用关键字let声明变量,rust鼓励使用自动类型推导。
- 默认来说,变量默认不可变。如果需要使得变量可变,则需要显式的声明为
mut
。rust鼓励使用不可变变量。
也可以指定类型,但是和C系语法不同,是标注在变量后面。对于习惯C系语法(C,java,js)的人来说,好不习惯。。。 - C系语法不需要定义函数的关键字,开头就是返回类型。于此不同,rust使用fn作为定义函数的关键字。
- rust中也有while循环和for循环。和C系语法不同,for循环是用来迭代列表。如果是需要迭代一个数字区间,
则可以使用(1..10)
,它实际上创建了一个Range<i32>
类型的对象并迭代。
接下来是将Vector转字符串的辅助函数:
fn vector_to_string(nums: &Vec<i32>) -> String { let mut s = String::new(); for i in nums.iter() { s += &(i.to_string() + " "); } return s; }
String::new
暗示出,rust中没有构造函数和new运算符。怎么创建对象?用静态工厂函数。
这个设计省了很多麻烦,首先,即使给你构造函数,工程实践上也会再封装一层各种工厂。
其次,你不会弄出一个初始化一半的对象。如java中的this引用泄漏。- String对象支持
+=
操作,这表明Rust支持运算符重载。
最后,main函数:
fn main() { let mut v = vec![9, 2, 5, 4, 8, 12, 1]; selection_sort(&mut v); println!("{}", vector_to_string(&v)); }
vec!
实际上是一个宏,rust支持强大的宏,强大到类似lisp的那种。&
是引用符,涉及到所有权和借用的概念。
学习方法与资料
对于有着一定基础的程序员,学习一门语言,个人觉得,最有效率的方式是:
- 结合现成的示例程序,学习语法教程。
- 写总结,按照自己的理解总结语法,写笔记。
- 写demo、造轮子。找几个典型的主题,写小demo、轮子试试手。
最后,有一些值得学习的资料:
- rust官方文档:https://www.rust-lang.org/zh-...
学习rust的主要资料。 - 《通过例子学习Rust》 https://rustcc.github.io/rust...
弥补Rust官方文档的不足,对于语法搭配一部分例子来参考。 - rust的awesome系列。https://github.com/rust-unoff...
最后
对于编程语言的理解,每个人有着不同的观点。
就我个人而言,我更赞同《代码大全》中的隐喻,即编程语言是程序员工具箱中的一把趁手的工具,
总体而言,它尽量使用良好的设计避免给程序员造成额外的负担,又具备强大的特性使得程序员可以优雅实现各类需求。
包括统一正交的语法、优秀的类型系统、不破坏统一性的适当的语法糖等。