这部分我们学习 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. 闪讯 开启wifi教程

    这是我自己试了几次之后发现的,也不是什么技术活. 首先说下,我的比较是小米pro笔记本,一般笔记本都是自带wifi功能的.如果要开wifi的话,必须是用网线连接才可以,通过wifi连接网络就不能开移动 ...

  2. scrollWidth、clientWidth 和 offsetWidth

    scrollWidth:对象的实际内容宽度,不包括边线宽度,会随对象中内容超过可视区而变大. clientWidth:对象内容的可视区的宽度,不包括边线宽度,会随对象显示大小的变化而变化. offse ...

  3. Yii 数据库重连告别General error: 2006 MySQL server has gone away

    General error: 2006 MySQL server has gone away 错误原因 制造错误 解决办法 最新办法 错误原因 Mysql has gone away MySQL 服务 ...

  4. OptimalSolution(8)--位运算

    一.不用额外变量交换两个整数的值 如果给定整数a和b,用以下三行代码即可交换a和b的值.a = a ^ b; b = a ^ b; a = a ^ b; a = a ^ b :假设a异或b的结果记为c ...

  5. SVM详细笔记及总结

    本文精品,如有疑问欢迎留言or微信咨询:523331232

  6. 机器学习笔记(一)· 感知机算法 · 原理篇

    这篇学习笔记强调几何直觉,同时也注重感知机算法内部的动机.限于篇幅,这里仅仅讨论了感知机的一般情形.损失函数的引入.工作原理.关于感知机的对偶形式和核感知机,会专门写另外一篇文章.关于感知机的实现代码 ...

  7. DB2中的MQT优化机制详解和实践

    MQT :物化查询表.是以一次查询的结果为基础  定义创建的表(实表),以量取胜(特别是在百万,千万级别的量,效果更显著),可以更快的查询到我们需要的结果.MQT有两种类型,一种是系统维护的MQT , ...

  8. CentOS6.5下安装JDK1.7+MYSQL5.5+TOMCAT7+nginx1.7.5环境安装文档

    ----------------CentOS6.5下安装JDK1.7+MYSQL5.5+TOMCAT7+nginx1.7.5环境安装文档----------------------- [JDK1.7安 ...

  9. u检验粗浅理解

    假设检验是以小概率事件,在一次实验中是不可能发生为前提(事实上是有可能发生的,但不是这样说的话,就落入一个圈,不能继续玩了),来否认原假设. u检验的定义: 已知从正态母体N(u,σ2)中抽得容量为n ...

  10. Django学习day4——视图和URL配置

    创建一个简单的hello world 在day3中我们第一次运行了服务器,里面是一个django的欢迎页面,那是因为我们没有配置URL和视图,django在底层会自动跳转这个页面上 我们在mysite ...