Rust教程:How to Rust-变量

这篇具有很好参考价值的文章主要介绍了Rust教程:How to Rust-变量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文为第1篇

专栏简介

本专栏是优质Rust技术专栏,推荐精通一门技术栈的蟹友,不建议完全无计算机基础的同学

感谢Rust圣经开源社区的同学,为后来者提供了非常优秀的Rust学习资源

本文使用:

  • 操作系统macOS Sonoma 14 / Apple M1
  • 编译器:Rustc & Cargo

感谢一路相伴的朋友们,感谢你们的支持 ^ _ ^

Rust教程:How to Rust-变量


目录

专栏简介

更新记录

前言

变量命名

原生标识符

变量绑定

可变变量

下划线开头的变量

变量遮蔽

结语

快捷翻页

本文参考文献


更新记录

2024.03.10 发布文章


前言

变量怎么命名?关键字有哪些?命名个和关键字名字一样的变量或者函数行不?变量绑定是啥?变量为啥还要可变?声明完不想用行不行?变量可以起一样的名字吗?


变量命名

在命名方面,Rust与其他编程语言并无显著区别,但当我们为变量、函数或类型等构造命名时,需要遵循一些既定的命名规则。这些规则有助于增强代码的可读性和一致性,具体规则可以看这里,一般来说,对于类型级别的构造(如结构体、枚举和特征),Rust倾向于使用驼峰命名法(CamelCase),即每个单词的首字母大写,且没有下划线分隔。而对于值级别的构造(如变量和函数参数),则推荐使用蛇形命名法(snake_case),即所有字母小写,单词之间用下划线分隔。

Rust语言包含一些保留关键字,这些关键字具有特殊的语法意义,因此不能被用作变量名或函数名。以下是一些常见的Rust关键字及其用途:

  • as - 强制类型转换,或use 和 extern crate包和模块引入语句中的重命名
  • break - 立刻退出循环
  • const - 定义常量或原生常量指针(constant raw pointer)
  • continue - 继续进入下一次循环迭代
  • crate - 链接外部包
  • dyn - 动态分发特征对象
  • else - 作为 if 和 if let 控制流结构的 fallback
  • enum - 定义一个枚举类型
  • extern - 链接一个外部包,或者一个宏变量(该变量定义在另外一个包中)
  • false - 布尔值 false
  • fn - 定义一个函数或 函数指针类型 (function pointer type)
  • for - 遍历一个迭代器或实现一个 trait 或者指定一个更高级的生命周期
  • if - 基于条件表达式的结果来执行相应的分支
  • impl - 为结构体或者特征实现具体功能
  • in - for 循环语法的一部分
  • let - 绑定一个变量
  • loop - 无条件循环
  • match - 模式匹配
  • mod - 定义一个模块
  • move - 使闭包获取其所捕获项的所有权
  • mut - 在引用、裸指针或模式绑定中使用,表明变量是可变的
  • pub - 表示结构体字段、impl 块或模块的公共可见性
  • ref - 通过引用绑定
  • return - 从函数中返回
  • Self - 实现特征类型的类型别名
  • self - 表示方法本身或当前模块
  • static - 表示全局变量或在整个程序执行期间保持其生命周期
  • struct - 定义一个结构体
  • super - 表示当前模块的父模块
  • trait - 定义一个特征
  • true - 布尔值 true
  • type - 定义一个类型别名或关联类型
  • unsafe - 表示不安全的代码、函数、特征或实现
  • use - 在当前代码范围内(模块或者花括号对)引入外部的包、模块等
  • where - 表示一个约束类型的从句
  • while - 基于一个表达式的结果判断是否继续循环

 以下关键字无任何功能,但仍然由 Rust 保留以备将来的应用

  • abstract
  • async
  • await
  • become
  • box
  • do
  • final
  • macro
  • override
  • priv
  • try
  • typeof
  • unsized
  • virtual
  • yield

原生标识符

原生标识符是Rust语言提供的一种机制,它允许开发者使用通常无法直接作为变量名、函数名或类型名等标识符的关键字。通过在关键字前加上r#前缀,开发者就可以“借用”这些关键字作为自定义的标识符,从而避免命名冲突和限制

例如,match是Rust中的一个关键字,用于实现模式匹配。如果我们尝试将match用作一个函数的名字,如下所示:

fn match(needle: &str, haystack: &str) -> bool
{
    haystack.contains(needle)
}

编译器提示:

error: expected identifier, found keyword `match`
 --> src/main.rs:4:4
  |
4 | fn match(needle: &str, haystack: &str) -> bool {
  |    ^^^^^ expected identifier, found keyword

编译器会直接报错,因为match是保留关键字,不能被用作普通函数名。此时,原生标识符就派上了用场。我们可以使用r#前缀来将match作为函数名称使用,如下所示:

fn r#match() -> i64
{
    let variable = 1;
    variable
}

fn main()
{
    let variable_output = r#match();
    println!("{}", variable_output)
}

通过这种方式,我们成功地规避了关键字带来的命名限制,实现了使用match作为函数名的目的。然而,需要注意的是,过度依赖原生标识符可能会导致代码可读性下降,因此在实践中应谨慎使用,并尽量使用更符合Rust命名习惯的替代方案


变量绑定

在JavaScript中,我们通常使用类似以下的方式为变量variable赋值:

var variable = "Hello World"

在上述代码中,计算机将等式右侧的字符串"hello world"赋值给变量variable。然而,在Rust中,我们采用了一种不同的方式来达到类似的效果:

let variable = "Hello World"

这个过程在Rust中被称为变量绑定,而不是赋值。那么,为什么Rust选择使用“绑定”这一术语而不是“赋值”呢?这背后涉及到Rust语言的核心原则——所有权。

简而言之,在Rust中,任何内存中的对象都有其特定的所有者,这个所有者完全掌控着该对象。当我们使用let关键字时,实际上是将一个内存对象绑定到一个变量上,这个变量随即成为该对象的所有者。与此同时,该对象之前的所有者(如果有的话)将失去对其的拥有权。这意味着在Rust中,一个对象在任何时刻只能有一个明确的拥有者。

这种所有权模型是Rust内存安全性的基石,它有助于防止诸如内存泄漏和悬挂指针等常见问题。通过明确绑定关系,Rust编译器能够跟踪哪些内存正在被使用,从而安全地进行清理和回收,确保程序的稳定运行。


可变变量

这个标题初听似乎有些出人意料,因为在大多数编程语言中,变量默认就是可变的。然而,在Rust中,情况恰恰相反。Rust中的变量默认是不可变的,包括我们之前提到的variable变量,其值一旦被绑定就不可再变。若需让变量可变,则需明确加上mut声明,类似下面这样

let mut variable = "Hello World"

这种语法可能初看起来有些多余,既然已经是变量了,为何还要额外声明它的可变性呢?

实际上,这种做法在大型项目中尤为重要。当一个变量被多处代码所引用时,有些代码可能期望该变量保持其原始值不变,而另一些代码则可能想要修改它。如果不加以明确声明,这种潜在的修改很难被及时发现,尤其是在多线程编程环境中,这种错误往往更为隐蔽和难以调试。因此,在Rust中通过mut关键字来明确变量的可变性,有助于提高代码的稳定性和可维护性。

这种规则让我们的代码逻辑变得非常清晰。当看到let关键字后面没有mut时,读者就能立即明白这个变量的值在后续代码中不会发生改变。而一旦看到mut,就像是给阅读代码的人打了“预防针”,提醒他们这个变量的值在后续可能会被更改


下划线开头的变量

如果你创建了一个变量却不在任何地方使用它,Rust通常会给你一个警告,因为这可能会是个 bug。但是有时创建一个不会被使用的变量是有用的,你希望能保留它,那么就可以在变量开头加上下划线(在C或C++中,下划线开头的变量是不被允许的,因为这可能是编译器使用的变量,但在Rust中,这是可以的)例如

fn main()
{
    let _variable_a = 5;
    let variable_b = 10;
}

在编译它时,Rust会提示

warning: unused variable: `variable_b`
 --> variable.rs:4:9
  |
4 |     let variable_b = 10;
  |         ^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_variable_b`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: 1 warning emitted

可以看到,两个变量都是只有声明,没有使用,但是编译器却独独给出了variable_b未被使用的警告,充分说明了_变量名前缀在这里发挥的作用

值得注意的是,这里编译器还很善意的给出了提示( Rust的编译器非常强大,这里的提示只是小意思 ): 将variable_b修改成 _variable_b即可


变量遮蔽

Rust 允许声明相同的变量名,在后面声明的变量会遮蔽掉前面声明的,例如

fn main()
{
    let variable = 5;
    let variable = variable + 1;

    {
        let variable = variable * 2;
        println!("{}", variable);
    }

    println!("{}", variable);
}

首先,数值 5 被绑定到变量variable。然后,通过使用let variable =重新声明并遮蔽了前面的variable,将其值更新为原值加 1,因此variable的值变为了 6。第三个 let 语句再次遮蔽了前面的variable,取用之前的值并乘以 2,最终variable的值变为 12。当运行此程序时,将输出以下内容:

$ ./shadowing
12
6

这种遮蔽机制与mut变量的使用有着显著的不同。mut允许我们在同一内存地址上修改变量的值,而不会发生内存对象的再分配,因此在性能上通常更优。而使用遮蔽时,每次let声明都会生成一个全新的变量,尽管它们恰好拥有相同的名称,但这实际上涉及到了内存对象的重新分配

变量遮蔽的用处在于,当我们在某个作用域内不再需要之前的变量(一旦被遮蔽,我们将无法再访问到之前的同名变量)时,可以重复使用变量名,这有助于避免绞尽脑汁去构思新的变量名,使代码更为简洁和清晰


结语

如果本文有任何问题欢迎在评论去指出,如果喜欢这篇文章,希望能点赞评论关注

如果你们身边有像你提起过这个领域的,或者希望可以和ta一起进步的,把这篇文章分享给ta吧

本文共4360字


快捷翻页

Rust教程:How to Rust-从开始之前到Hello World


本文参考文献

Rust圣经

文心一言文章来源地址https://www.toymoban.com/news/detail-840209.html

到了这里,关于Rust教程:How to Rust-变量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Rust软件外包开发语言的特点

    Rust 是一种系统级编程语言,强调性能、安全性和并发性的编程语言,适用于广泛的应用领域,特别是那些需要高度可靠性和高性能的场景。下面和大家分享 Rust 语言的一些主要特点以及适用的场合,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公

    2024年02月12日
    浏览(51)
  • 【Rust 基础篇】Rust可变静态变量:全局状态的可变性管理

    Rust是一种以安全性和高效性著称的系统级编程语言,其设计哲学是在不损失性能的前提下,保障代码的内存安全和线程安全。为了实现这一目标,Rust引入了\\\"所有权系统\\\"、\\\"借用检查器\\\"等特性,有效地避免了常见的内存安全问题。然而,有时候我们需要在程序的整个生命周期

    2024年02月15日
    浏览(36)
  • Rust-变量

    Rust的变量必须先声明后使用。对于局部变量,最常见的声明语法为: 与传统的C/C++语言相比,Rust的变量声明语法不同。这样设计主要有以下几个方面的考虑。 语法分析更容易 从语法分析的角度来说,Rust的变量声明语法比C/C++语言的简单,局部变量声明一定是以let开头

    2024年01月21日
    浏览(53)
  • Rust- 变量绑定

    In Rust, you bind values to a variable name using the let keyword. This is often referred to as “variable binding” because it’s like binding a name to a value. Here’s a simple example: In this example, x is bound to the value 5 . By default, bindings are immutable in Rust. If you try to reassign x to a different value, you’ll get a compile-time err

    2024年02月14日
    浏览(30)
  • Rust 基础入门 —— 变量绑定与解构

    摸个笔记 首先讨论的第一点,就是对于传统的开发者来说明:为什么要去用 这样手动设定的方式设定变量的可行性。 Course给出的解释是——苦一苦开发,乐一乐运维。 好吧,让我们理解,程序员的懒惰和贪婪是无止境的,我们想要一种类型自行推断,但是性能提高、安全非

    2024年02月09日
    浏览(38)
  • Rust 学习笔记 - 变量声明与使用

    任何一门编程语言几乎都脱离不了:变量、基本类型、函数、注释、循环、条件判断,这是一门编程语言的语法基础,只有当掌握这些基础语法及概念才能更好的学习 Rust。 Rust 是一种强类型语言,但在声明变量时,不总是需要显式声明类型,这是因为 Rust 的编译器有类型推

    2024年02月19日
    浏览(41)
  • Rust语法:变量,函数,控制流,struct

    可变与不可变变量 Rust中使用let来声明变量,但是let声明的是不可变变量,如果想要可变,则需要加上mut 变量与常量 常量与不可变变量一样都是不能被修改的,但是他与不可变变量有很多区别。 常量用const声明,且必须标注其类型 常量不能加mut修饰 常量可以在任何作

    2024年02月13日
    浏览(39)
  • Rust变量、常量声明与基本数据类型

    Rust是一门系统级别的编程语言,注重安全性、性能和并发。在这篇博客中,我们将介绍Rust中的变量、常量声明以及基本数据类型,并通过示例说明每一种类型的用法。 在Rust中,使用 let 声明变量。变量默认是不可变的,要使其可变,需要使用 mut 。 常量使用

    2024年01月18日
    浏览(62)
  • Rust - 变量与数据的交互方式(clone)

     在上一篇文章中我们介绍了变量与数据的交互方式-move,通过底层原理我们知道Rust 永远也不会自动创建数据的 “深拷贝”。因此,任何  自动 的复制可以被认为对运行时性能影响较小。 但是如果我们  确实 需要深度复制  String 中堆上的数据,而不仅仅是栈上的数据,可

    2024年01月22日
    浏览(70)
  • 【Rust】001-基础语法:变量声明及数据类型

    “一切能用 Rust 重写的项目都将或者正在用 Rust 重写” Rust 入门与实践:https://juejin.cn/book/7269676791348854839?utm_source=course_list 代码演示 执行结果 依赖 Cargo.toxml 代码 执行命令 根目录执行 整型标量类型 只要记得最低从 8 开始,到 128 结束(当然,正常情况下我们最多用到 64,

    2024年02月10日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包