讲动人的故事,写懂人的代码
- 故事梗概:
- 在她所维护的老旧Java系统即将被淘汰的危机边缘,这位在编程中总想快速完事的女程序员,希望能转岗到公司内部使用Rust语言的新项目组,因此开始自学Rust;
- 然而,在掌握了Rust编程知识之后,为了通过Rust项目组的技术面试,使得转岗成功而不至被裁员,她必须领会编程如何"快速"才能有真正的意义。
上次我们聊到,我们那三个程序员小伙伴一起钻研了Rust的prelude和宏。他们还在继续深入研究代码。
赵可菲:“那个给 guess
赋值的语句,没写明类型,看来Rust是自动帮我们判断类型的吧。”
let mut guess = String::new();
贾克强:“没错,Rust是会自动帮我们判断类型,这样代码看起来就更简洁了。但是要注意那句话其实是在做变量绑定(binding),不是赋值哦。”
4.1 默认不可变的变量绑定
贾克强:“在Rust中,我们用let
关键字把一个值和一个变量名绑定在一起。”
“这个过程可能会涉及到类型推断和类型标注,但类型标注是可选的,所以不用太担心。”
“默认情况下,变量绑定的值是不能改变的,也就是说,一旦你把一个值绑定到一个变量,那这个变量的值就不能改变了。”
“但是,如果你在声明变量的时候用了mut
关键字,那这个变量就可以改变了,很灵活。”
席双嘉:“在C++里是没有这个变量绑定的概念。”
赵可菲:“Java里也没有变量绑定。那在Rust里就没有变量赋值吗?”
贾克强:“在 Rust 语言中,赋值语句的概念确实还是存在的,但它和变量绑定不一样,两者在用法和含义上有不少区别。”
“赋值语句在 Rust 中用来修改已经绑定的变量的值。如果变量是可变的,也就是用 mut
声明的,那就可以对其进行重新赋值。”
“比如在我们的代码中的这两行。上面一行就是变量绑定,非常简洁。然后下面一行的.read_line(&mut guess)
,这个方法调用,就是对 guess
变量进行赋值的。”
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
”read_line
方法尝试从标准输入(stdin
)读取一行数据,并会把读取的内容追加到 guess
字符串的末尾。”
”在这里,&mut guess
是对 guess
的可变引用,这让 read_line
方法可以修改 guess
的内容。”
“注意,&
意味着guess这个参数是个引用。引用默认也是不可变的。”
赵可菲:“嘿,为啥Rust要设计变量绑定这样的机制呢?有啥好处不?”
贾克强:“Rust的变量绑定跟Java或C++的赋值不一样,其实主要是体现了更深的语言设计原则和变量行为的差别。”
“变量绑定除了默认不可变这点,还包括变量值的所有权和范围的特性。”
“Rust的所有权模型就是,你给一个值取个名字的时候,也在定义这个值的有效范围,以及对它的内存管理的责任。”
“这个概念跟Rust的所有权、借用和生命周期系统紧紧相连,跟Java和C++的内存管理模型可是大不一样呢。”
4.1.1 默认可变的Java 和 C++ 中的赋值
贾克强:“在 Java 和 C++ 这种语言里,‘赋值’这个词就像是直接把操作摆上桌面。”
“首先,就是默认都可以改。跟 Rust 不一样,在 Java 和 C++ 里,变量默认都是可以随便改的。你给一个变量赋个值,然后就可以随便改。”
“然后就是内存管理。Java 是靠垃圾收集来管理内存的。C++ 就需要你自己去管理内存,比如用 new