这部分我们学习 rust 语言的 变量、数据类型、函数、注释、流程控制 这五个方面的内容。本文我们介绍前两个内容,下一篇文章介绍后三个内容。

变量

默认情况下,rust 语言中声明的变量是不可变的,比如如下代码:

fn main() {
let x = 5;
println!("x 的值是: {}", x);
x = 6;
println!("x 的值是: {}", x);
}

我们先来跑一下这段代码:

cargo run
Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
error[E0384]: cannot assign twice to immutable variable `x`
--> src/main.rs:4:5
|
2 | let x = 5;
| -
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
3 | println!("x 的值是: {}", x);
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable error: aborting due to previous error For more information about this error, try `rustc --explain E0384`.

通过运行结果,我们发现这段代码有问题的,然后我们从报错信息中抓取关键信息: cannot assign twice to immutable variable,它的意思是 不可变变量不能进行二次赋值。但是有些时候,我们也需要修改变量的值,应该怎么办呢,在变量名的前面,let 关键字的后面添加一个关键字 mut 就行了,我们来试试:

fn main() {
let mut x = 5;
println!("x 的值是: {}", x);
x = 6;
println!("x 的值是: {}", x);
}

运行一下代码:

cargo run
Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 3.53s
Running `target/debug/hello_cargo`
x 的值是: 5
x 的值是: 6

这种不可变变量的设计有着很多安全方面的考虑,这里不再赘述。谈到这里,很容易联想到编程语言的另一个概念——常量,那二者有什么区别呢?

1.常量不能使用 mut 关键字修饰,常量在任何情况下都是不可变的(变量是在默认情况下不可变)。

2.常量使用 const 关键字来声明,而变量使用 let 关键字来声明。

3.常量需要在常量名后面紧跟冒号和类型,例如 const MAX_POINTS: u32 = 100_000;,而变量可以省略冒号和类型的修饰。

4.常量的作用域是任何作用域,包括全局作用域。

5.常量只能使用常量表达式赋值,而不能使用函数结果或者其它运行时产生的值。

注:这是说明一下,常量通常使用大写字母和下划线 _ 来命名。

我们再来说一个变量的特性——覆盖。在上一篇写猜数字游戏的文章中,我们做数字类型转换的时候,新类型的名字使用了旧类型的名字,这种情况就是覆盖。先来个实例:

fn main() {
let x = 5;
println!("x 的值是: {}", x);
let x = 6;
println!("x 的值是: {}", x);
}

我们来看运行结果:

cargo run
Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.36s
Running `target/debug/hello_cargo`
x 的值是: 5
x 的值是: 6

通过结果可以发现,第二个使用 let 关键字修饰的不可变变量 x 把第一个 x 覆盖了,也就是说把 x 的值从 5 改成了 6。那这和 mut 有什么区别呢?

1.覆盖的第二个变量需要使用 let 关键字修饰,如果没有 let 关键字,则会报错。

2.覆盖的第二个变量不仅可以改变值,还可以修改变量的类型;而 mut 不可以改变类型。

这里举两个例子来说明第二个区别:

fn main() {
let space = "abc";
println!("space 代表的是:{}", space);
let space = space.len();
println!("space 代表的是:{}", space);
}

先来运行第一个例子:

 cargo run
Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.22s
Running `target/debug/hello_cargo`
space 代表的是:abc
space 代表的是:3

然后看第二个例子:

fn main() {
let mut space = "abc";
println!("space 代表的是:{}", space);
space = space.len();
println!("space 代表的是:{}", space);
}

跑一下第二个例子:

cargo run
Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
error[E0308]: mismatched types
--> src/main.rs:4:13
|
4 | space = space.len();
| ^^^^^^^^^^^ expected &str, found usize
|
= note: expected type `&str`
found type `usize` error: aborting due to previous error For more information about this error, try `rustc --explain E0308`.
error: could not compile `hello_cargo`. To learn more, run the command again with --verbose.

可以轻易看到二者的区别,好了,接下来我们看 rust 的基本类型。

数据类型

rust 的数据类型就是在编译期间告诉 rust 的编译器如何处理这些数据。在这里,我们会了解到两种数据类型:基本数据类型和组合数据类型。

基本数据类型

基本数据类型也就是简单值,rust 主要包含了 4 种基本数据类型,分别是整型、浮点型、布尔型和字符型。你可能在其他语言中见过这些类型,现在,我们来看一下它们在 rust 语言中是怎么样的。

整型

整型是不包含小数的数字类型。整型包含了两种类型:i 打头的有符号整型和 u 打头的无符号整型。我们使用一个表格来描述 rust 的整型:

占用空间 有符号整型 无符号整型
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128
格式 i+长度 u+长度

整型在使用过程中默认类型是 i32。

浮点型

浮点型包含了两种类型:单精度浮点型 f32,双精度浮点型 f64。浮点型在使用过程中默认类型是 f64。

数据操作

rust 支持的基本数据操作有:加 +,减 -,乘 *,除 /,取模 %。

布尔型

布尔型通常有两个值:true和false。它占用 1 个字节,使用 bool 关键字来声明。

字符型

rust 的字符类型占用 4 个字节,它的值是使用单引号 ' 引起来的。

组合数据类型

组合数据类型是把多个值组合成一个类型。在 rust 中,组合数据类型有两种:元组和数组。

元组

元组是把多个基本类型组合成一个组合类型。它有一个确定的长度,一旦确定就不能再次加减元素了。我们先来看一个元组的实例:

fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
println!("第0个值:{}, 第1个值:{}, 第2个值:{}", tup.0, tup.1, tup.2); let (x, y, z) = tup;
println!("x的值:{}, y的值:{}, z的值:{}", x, y, z);
}

它运行的结果是:

cargo run
Compiling hello_cargo v0.1.0 (/Users/shanpengfei/work/rust-work-space/study/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.23s
Running `target/debug/hello_cargo`
第0个值:500, 第1个值:6.4, 第2个值:1
x的值:500, y的值:6.4, z的值:1

元组的取值有两种方式,一种是把元组解构成多个变量,另一种就是使用 . 的方式,顺序是从 0 开始。

数组

数组和元组不一样的地方是:数组只能使用相同的数据类型。数组和元组相同的地方是:长度一旦确定就不能加减元素了。如果想改变数组的长度,可以使用 vector 类型,后续文章会介绍 vector 类型的情况。而且数组还有一个特性,它会把数据分配到栈内存,而不是堆内存。下面举几个常用的数组的例子:

fn main() {
// 定义一个简单的数组
let a = [1, 2, 3, 4, 5]; // 定义一年 12 个月,而且不需要增减月份,那么可以直接定义包含 12 个月份的数组
let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; // 定义包含 5 个元素的 i32 类型的数组
let a: [i32; 5] = [1, 2, 3, 4, 5]; // 数组的值是 5 个 3
let a = [3; 5]; // 取值
println!("a[3]的值是:{}", a[3]);
println!("a[9]的值是:{}", a[9]); // 编译时这里会报错:error: index out of bounds: the len is 5 but the index is 9
}

数组的取值方式是以中括号 [0] 的方式,顺序是从 0 开始。如果取值越界,rust 会在编译期告诉你,这就是 rust 安全原则的第一个例子。

这一节未完,待续~~~

欢迎阅读单鹏飞的学习笔记

Rust 入门 (三)_上的更多相关文章

  1. Rust 入门 (三)_下

    这部分我们学习 rust 语言的 变量.数据类型.函数.注释.流程控制 这五个方面的内容.前文介绍了前两个内容,本文介绍后三个内容. 函数 函数在 rust 代码普遍存在,我们也已经见过了它的主函数 ...

  2. ArcGIS for Desktop入门教程_第三章_Desktop软件安装 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第三章_Desktop软件安装 - ArcGIS知乎-新一代ArcGIS问答社区 1 软件安装 1.1 安装前准备 请确认已经收到来自Esri中国( ...

  3. Rust入门篇 (1)

    Rust入门篇 声明: 本文是在参考 The Rust Programming Language 和 Rust官方教程 中文版 写的. 个人学习用 再PS. 目录这东东果然是必须的... 找个时间生成 ...

  4. GEF入门实例_总结_06_为编辑器添加内容

    一.前言 本文承接上一节:GEF入门实例_总结_05_显示一个空白编辑器 在上一节我们为我们的插件添加了一个空白的编辑器,这一节我们将为此编辑器添加内容. 二.GEF的MVC模式 在此只简单总结一下, ...

  5. GEF入门实例_总结_05_显示一个空白编辑器

    一.前言 本文承接上一节:GEF入门实例_总结_04_Eclipse插件启动流程分析 在第三节( GEF入门实例_总结_03_显示菜单和工具栏  ),我们创建了菜单和工具栏. 这一节,我们来实现:点击 ...

  6. GEF入门实例_总结_04_Eclipse插件启动流程分析

    一.前言 本文承接上一节:GEF入门实例_总结_03_显示菜单和工具栏 注意到app目录下的6个类文件. 这6个文件对RCP应用程序而言非常重要,可能我们现在对这几个文件的理解还是云里雾里,这一节我们 ...

  7. GEF入门实例_总结_03_显示菜单和工具栏

    一.前言 本文承接上一节: GEF入门实例_总结_02_新建初始RCP空项目 这一节,我们来给我们的插件加上菜单. 二.基础知识 1.action bar.menubar.coolbar   含义 a ...

  8. GEF入门实例_总结_02_新建初始RCP空项目

    一.前言 本节承接上一节: GEF入门实例_总结_01_教程.源码.开发环境准备 这一节我们来创建一个空的RCP项目. 二.新建RCP项目 1. New 一个 Plug-in Project 2.输入 ...

  9. ArcGIS for Desktop入门教程_第七章_使用ArcGIS进行空间分析 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第七章_使用ArcGIS进行空间分析 - ArcGIS知乎-新一代ArcGIS问答社区 1 使用ArcGIS进行空间分析 1.1 GIS分析基础 G ...

随机推荐

  1. Intellij idea 一个窗口打开多模块并添加依赖

    打开多模块 ctrl+alt+shift+s 或者file->project sturcture 选择modules 添加 选择要添加的模块 选择从现有模块添加,不要选择从现在代码创建模块 添加 ...

  2. vscode自定义颜色主题插件并发布

    生成一个新的颜色主题 运行命令 npm install -g yo generator-code yo code 这时默认文件目录已经帮你创建好了 vscode中按下F5可以帮你打开调试,预览创建好的 ...

  3. 函数进阶(三) day14

    目录 昨日内容 迭代器 可迭代对象 迭代器对象 for循环原理 三元表达式 列表推导式 字典生成式 zip 生成器表达式 生成器 yield 递归 今日内容 匿名函数 内置方法 掌握 了解 异常处理 ...

  4. django-URL重定向(八)

    HttpResponseRedirect()不常用 redirect(to,permanent=False,*args,**kwargs) to:指重定向的位置,可以是视图,也可以是url地址,也可以 ...

  5. BOOL,int,float,指针变量 与“零值”比较的if语句

    分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var) 解答: BOOL型变量:if(!var) int型变量: if(var==0) float型变量: ...

  6. 如何使用git上传代码

    首先在github 上创建好远程仓库,并拷贝仓库地址,接下来按照以下步骤:   1.打开命令行进入要上传的文件目录,初始化 git init  2. 建立远程仓库,git remote add ori ...

  7. CSPS模拟 48

    ??? 分数越来越低??? T1 String Master 题目过于毒瘤,以至于我都不想改 T2 Tourist Attractions 稍微转化题意是求无向图的三角形个数 由于坚信bitset不是 ...

  8. 使用Typescript重构axios(二十)——请求取消功能:实现第一种使用方式

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  9. UiPath之文件操作

    今天给大家介绍一下,在UiPath中如何操作文件,比如需要在某个文件夹中自动创建一个当天日期的文本. 主要使用的activity有: l  Assign l  Path Exists l  If l  ...

  10. [转载]2.7 UiPath Flowchart的介绍和使用

    一.Flowchart的介绍 用于更复杂的业务逻辑. 与序列不同的是, 流程图提供了多个分支逻辑运算符, 可以使用流程图创建复杂的业务流程并以多种方式连接每个活动. 二.在UiPath 使用Flowc ...