其实我一直弄不明白一点,那就是计算机技术的发展,是让这个世界变得简单了,还是变得更复杂了。
当然这只是一个玩笑,可别把这个问题当真。

然而对于IT从业者来说,这可不是一个玩笑。几乎每一次的技术发展,都让这个生态变得更为复杂。“英年早秃”已经成为一种很普遍的现象。

Rust是近两年呼声比较高的一种新型开发语言。市场占有量并不大,但增长速度极为迅猛。
有人统计过,在计算机行业,平均每33.5天就有一种所谓的新型开发语言面世,这还不包括很多企业内部、项目内部的内置简易流程工具。然而大浪淘沙,如今仍然占据着市场地位的,不过仍然是耳熟能详的有限几种。
作为新来的搅局者,Rust到底值不值得学习并且在工作中应用呢?

先说结论,这里粗略的把开发者分为初学者、小有经验的常规工程师和资深开发者三类。
对于初学者,Rust具有比较陡峭的学习曲线,虽然学习Rust能训练良好的编程习惯,从长远看对提高学习者的开发素养极具价值。但短期的大量付出很容易让初学者心力交瘁。并且尽管官方文档并不欠缺,但学习资料对于初学者来讲仍然是远远不够的。所以比较而言,得不偿失。因此建议初学者仍然由久经验证的语言入门加入软件开发的大家庭。比如说C/Java/Python/Js都是很好的入门选择。
对于有一定经验的常规工程师,他们已经有了一段时间的开发工作实践,对于软件开发的现状、发展都已经形成了自己的世界观。如果感觉并不很喜欢这个行业,希望将来转行管理岗位或者产品岗位。那当前应当做的更多是倾向业务领域,了解业务和技术的衔接和互动,完全不需要学习Rust。而如果醉心于技术,并从中获得了自己的乐趣,希望逐步提高自己的技术水平。那么Rust会是一个很好的桥梁,哪怕仅仅学习Rust而并不将其应用于工作,也能让开发者从中获取大量的有益习惯和软件底层经验,从而形成自己良好的代码风格。
对于资深工程师,即便并不从而底层系统级的开发工作,Rust也是一门很优秀的语言。它能弥补当前多种开发语言的不足,形成良好的开发哲学和思想导向,帮助开发者交付高质量的软件产品。因此,及早学习并应用Rust非常有价值。

为了说明这个结论,下面从多个角度,采用同传统语言对比的方式来说一说我对Rust的理解。

Rust是一种全面创新的语言

这几年有不少有影响的语言出现,但大多数都只是关键字或者小范围的语法创新,随后可能会有大量的特色库函数来丰富语言的功能。一个有经验的开发者,可能翻两天资料,就能快速的掌握。
而Rust极具自身语言特点,是一种完全的创新,而不是简单的语法替换。简单的熟悉几个关键字和判断、循环等语法,远不足以掌握这门语言。
为了证明这一点,下面用Rust的“所有权”(Ownership)机制和“遮蔽”(Shadowing)来举例说明。

“所有权”机制(Ownership)和“遮蔽”(Shadowing)

以C++为例,请看下面这段代码:

#include<iostream> using namespace std;  int main(){     string s1="hello";     string s2=s1;     cout << "s1=" << s1 << ",s2=" << s2 << endl;     return 0; }

编译执行后,程序输出:

s1=hello,s2=hello

代码再简单不过,首先声明、赋值一个字符串变量s1,然后把变量s1赋值给变量s2,最后输出两者的值。

对应的,我们看一个Rust的版本:

fn main(){     let s1=String::from("hello");     let s2=s1;     println!("s1={},s2={}",s1,s2); }

除了细小的语法差异,看上去跟C++的版本没有什么不同。然而在Rust中,这段代码连编译都无法通过,得益于rustc编译程序详细的输出,我们能看到很细致的错误提示:

2 |     let s1=String::from("hello");   |         -- move occurs because `s1` has type `std::string::String`, which does not implement the `Copy` trait 3 |     let s2=s1;   |            -- value moved here 4 |     println!("s1={},s2={}",s1,s2);   |                            ^^ value borrowed here after move

这个编译错误是指,上面代码中,当变量s1赋值给s2之后,s1变量名所指向的内存所有权,被“转移”(move)到了s2变量名拥有之下。而从此之后,s1变量名就无效了,不再指向任何一块内存。除非重新声明并为s1赋值(Rust中称为Shadow,"遮蔽"原有的s1),s1不能再被使用。
所有权机制可以有效的防止内存泄露所导致的程序Bug,是Rust内存管理的核心理念。上面提到的所有权“转移”是所有权管理的重要特征之一。

“遮蔽”也是一个有趣的概念,Rust的处理方式跟很多我们熟悉的语言不同。
请看下面C语言代码:

#include<stdio.h>  int main(){     int x = 5;     x = x+1;     printf("x=%d\n", x); }

这又是一段很基本的代码。首先声明、赋值一个整数变量x,接着把x的值加1,再赋值回变量x。这是各种开发语言中都常见的用法。编译执行的输出结果为x=6
来看看Rust的版本:

fn main(){     let x=5;     x = x+1;     println!("x={}", x); }

很不幸,这段代码同样无法编译通过,错误是:

error[E0384]: cannot assign twice to immutable variable `x`  --> test-own1.rs:3:5   | 2 |     let x=5;   |         -   |         |   |         first assignment to `x`   |         help: make this binding mutable: `mut x` 3 |     x = x+1;   |     ^^^^^^^ cannot assign twice to immutable variable