rust语言特性之变量

云水木石 云水木石     2023-02-05     248

关键词:

学习一门新的语言中,我写下 2023 年的新目标:学习 RUST 语言。这几天我把 RUST 语法过了一遍。

有了其它编程语言的基础,RUST 语法学起来不难。但 RUST 毕竟是一门全新设计的语言,如果和现有语言完全一样,那就失去了存在的价值。RUST 作为一门年轻的语言,博采众长,在设计上进行了取舍,所以有很多独特之处。今天我就来聊一聊 RUST 语言中的变量。

所有的编程语言都有变量,RUST 语言在设计上独特地方在于:

  1. Rust中的变量默认是不可变的。

  2. 一个新声明的变量可以覆盖掉旧的同名变量。

如果仅仅是学习语言,这两点特性掌握起来也很简单,在这里我想探讨的是背后的设计理念。

不变量与常量

首先,需要澄清一下,不可变变量并不是常量,RUST 语言提供了常量(关键词 const,这一点和 Java 有所不同)。

在 RUST 中,常量不仅是默认不可变的,它还总是不可变的,而变量虽然默认不可变,但可以添加关键字 mut 使其可变。

常量的值必须在编译器就能确定,所以你无法将一个函数的返回值,或其他需要在运行时计算的值绑定到常量上,这一点其它的编程语言也有这种要求,不可变量的值可以运行时确定。

此外,常量在整个程序运行的过程中都在自己声明的作用域内有效,这使得常量可以被用于在程序的不同代码之间共享值,这个在后面探讨作用域时再进一步分析。

为什么变量默认不可变

变量不可变,在其它语言上也有这样的设计。比如 Java 语言,变量前加上 final 修饰词,在 C++ 中,const 可用来修饰指针变量、函数参数、函数返回值、成员变量、。。。表明这些变量不会被修改。但在这些语言中,变量默认是可以修改,RUST 默认变量不可变,这背后的考量是什么?

我觉得这背后的设计理念就是人总是懒惰的,会倾向于使用更简短的写法。就拿 C++ 语言来说吧,很多时候函数传递指针或引用时,不修改指针或者引用的值,仅仅是为了减少对象拷贝的开销,这个时候应该在前面加上 const 修饰词,但很多程序员不会加。不信你可以看看自己写的 C++ 代码,有没有给不修改成员变量的成员函数加上 const 修饰符。

所以默认不可变的第一个好处,是提高了不可变量的使用频次。let a也能用,let mut a,也能用,那么大部分时候,大家会省去mut。

默认不可变的另一个好处是,简化逻辑。在多线程编程中,最大的麻烦是数据竞争,假如语法层面保证了一个值的不可变,就不需要锁保护(当然这只是一方面)。

变量可以被覆盖(隐藏),这是什么逻辑

看看如下代码,就可以明白什么叫变量覆盖:

let mut guess = String::new();

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

    let guess: u32 = guess.trim().parse()
        .expect("Please type a number!");

    println!("You guessed: ", guess);

这段代码中,guess 变量先是 String 类型,接着又改变其类型为 u32。这在我所学过的语言中都是不被允许的。这背后的逻辑是什么?

我认为还是为了精简代码。我们是否也经常碰到为了取变量的不同类型值,为变量名取 xxx_str 之类的不同的名字。比如坐标计算中,有的使用浮点型、有的使用整型,为类型转化中间变量取名就很头疼。有了 RUST 这种语言特性,不需要为了一些中间变量取一些特别的名字。

在 C 中,如果我们写了多个循环语句,可能需要使用上 i, j, k 之类的循环变量,在 RUST 语言中一个 i 变量就可以。

当然,变量改变了类型可能会引起程序员的困惑,但由于编译器的强大,如果在代码中使用了错误的变量类型,在编译期间就可以检查出来。而变量类型定义和使用变量的代码离得更近,逻辑上更清晰,更不容易出错。


当然,关于 RUST 语言的语法还有很多可以探讨的,但大多数只是和其它语言在定义上有所不同,理念上一致,不需要特别讨论。但 RUST 语言中的所有权是一个非常独特的设计,这个值得重点说一说,下一篇文章中,我将探索 RUST 语言中的 所有权,敬请关注。

rust编程语言入门之高级特性(代码片段)

...函数和闭包宏一、不安全Rust匹配命名变量隐藏着第二个语言,它没有强制内存安全保证:UnsafeRust(不安全的Rust)和普通的Rust一样,但提供了额外的“超能力”UnsafeRust存在的原因:静态分析是保守的。使用UnsafeRust:我知道自己... 查看详情

rust编程语言入门之函数式语言特性:-迭代器和闭包(代码片段)

函数式语言特性:-迭代器和闭包本章内容闭包(closures)迭代器(iterators)优化改善12章的实例项目讨论闭包和迭代器的运行时性能一、闭包(1)-使用闭包创建抽象行为什么是闭包(closure)闭包:可以捕获其所在环境的匿名函数... 查看详情

rust语言特性之所有权

新年开工,开启work&study模式,接着来学习RUST语言。作为一名C/C++程序员,C/C++语言中的指针是使用得最爽的,几乎无所不能,各种奇技淫巧也层出不穷。但C/C++语言中最折磨人的也是指针&#... 查看详情

rust编程语言入门之rust的面向对象编程特性(代码片段)

Rust的面向对象编程特性一、面向对象语言的特性Rust是面向对象编程语言吗?Rust受到多种编程范式的影响,包括面向对象面向对象通常包含以下特性:命名对象、封装、继承对象包含数据和行为“设计模式四人帮”在《设计模型... 查看详情

rust学习--变量(代码片段)

0x0每种编程语言都有变量的概念,我们可以把变量理解为最简单的存储方式,它是编码过程中是必不可少的。Rust的变量很有特色。变量不可变的特性让人想起了Erlang。以及后面的模式匹配,我觉得作者应该受Erlang影响很大。下... 查看详情

rust编程语言入门之项目实例:-命令行程序(代码片段)

项目实例:-命令行程序一、实例:接收命令行参数本章内容12.1接收命令行参数12.2读取文件12.3重构:改进模块和错误处理12.4使用TDD(测试驱动开发)开发库功能12.5使用环境变量12.6将错误消息写入标准错误而不是标准输出创建... 查看详情

「rust进阶笔记」rust之derive特性总结(代码片段)

前言编译器可以通过#[derive]为一些trait提供基础的实现。如果需要更复杂的逻辑,这些trait也可以被手动实现。这些可导入的实现:比较:Eq、PartialEq、Ord、PartialOrdClone:从&T的一个拷贝创建TCopy:把一个类型的move转换为copyHash:... 查看详情

rust所有权

...有者(变量)离开作用域,这个值将被丢弃。引用和Copy特性赋值过程:包括变量赋值,函数传参,函数返回如果类型实现了Copy特性(基本简单类型),传参过程相当于创建了一份新拷贝 查看详情

rust编程语言入门之模式匹配(代码片段)

模式匹配模式模式是Rust中的一种特殊语法,用于匹配复杂和简单类型的结构将模式与匹配表达式和其他构造结合使用,可以更好地控制程序的控制流模式由以下元素(的一些组合)组成:字面值解构的数组、enum、struct和tuple变... 查看详情

rust学习内存安全探秘:变量的所有权引用与借用

作者:京东零售周凯一.前言Rust语言由Mozilla开发,最早发布于2014年9月,是一种高效、可靠的通用高级语言。其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言。Rust语言具备... 查看详情

rust入坑指南之ownership

...ust编译器会捕获很多C++难以发现的错误”。BrianKernighan:C语言的创始人之一,对Rust的评价是:“Rust是一门非常强大的程序语言,在资源管理、内存安全、多线程等方面具有很强的能力”。RobPike:Go语言的创始人之一,对Rust的评... 查看详情

rust编程语言入门之编写自动化测试(代码片段)

编写自动化测试一、编写和运行测试测试(函数)测试:函数验证非测试代码的功能是否和预期一致测试函数体(通常)执行的3个操作:准备数据/状态运行被测试的代码断言(Assert)结果解剖测试函数测试函数需要使用test属性... 查看详情

rust学习教程02-rust语言简介

本文节选自<<Rust语言圣经>>一书欢迎大家加入Rust编程学院,一起学习交流:QQ群:1009730433进入Rust编程世界一、Rust发展历程Rust最早是Mozilla雇员GraydonHoare的一个个人项目,从2009年开始,得到了Mozilla研究院的... 查看详情

microsoftsqlserver2022新特性之t-sql语言增强(代码片段)

MicrosoftSQLServer2022已经正式发布,可以下载使用。本文给大家介绍一下该版本中的部分T-SQL新功能。窗口函数增强新版本中的窗口函数支持命名窗口(WINDOW)子句,可以利用该子句定义窗口变量,然后在OVER子句... 查看详情

microsoftsqlserver2022新特性之t-sql语言增强(代码片段)

MicrosoftSQLServer2022已经正式发布,可以下载使用。本文给大家介绍一下该版本中的部分T-SQL新功能。窗口函数增强新版本中的窗口函数支持命名窗口(WINDOW)子句,可以利用该子句定义窗口变量,然后在OVER子句... 查看详情

一天一门编程语言rust语言程序设计极简教程(代码片段)

文章目录Rust语言程序设计极简教程介绍安装RustHello,World基础语法变量及数据类型控制结构`if`语句`while`语句`for`语句函数泛型泛型的语法泛型的应用TraitTrait的定义Trait的实现Trait的继承模式匹配模式匹配的语法... 查看详情

rust语言中级教程之指针(代码片段)

Rust语言中级教程一、指针什么是指针指针是计算机引用无法立即直接访问的数据的一种方式(类比书的目录)数据在物理内存(RAM)中是分散的存储着地址空间是检索系统指针就被编码为内存地址,使用usize类型的整数表示。一... 查看详情

rust编程指南02-进入rust语言世界(代码片段)

...惑Rust为啥用了这么久才到1.0版本?与之相比,Go语言2009年发布,却在2012年仅用3年就发布了1.0版本。首先是因为Rust语言特性较为复杂,因此需要全盘考虑的问题非常多; 查看详情