Rust 入门 (三)_上
这部分我们学习 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 入门 (三)_上的更多相关文章
- Rust 入门 (三)_下
这部分我们学习 rust 语言的 变量.数据类型.函数.注释.流程控制 这五个方面的内容.前文介绍了前两个内容,本文介绍后三个内容. 函数 函数在 rust 代码普遍存在,我们也已经见过了它的主函数 ...
- ArcGIS for Desktop入门教程_第三章_Desktop软件安装 - ArcGIS知乎-新一代ArcGIS问答社区
原文:ArcGIS for Desktop入门教程_第三章_Desktop软件安装 - ArcGIS知乎-新一代ArcGIS问答社区 1 软件安装 1.1 安装前准备 请确认已经收到来自Esri中国( ...
- Rust入门篇 (1)
Rust入门篇 声明: 本文是在参考 The Rust Programming Language 和 Rust官方教程 中文版 写的. 个人学习用 再PS. 目录这东东果然是必须的... 找个时间生成 ...
- GEF入门实例_总结_06_为编辑器添加内容
一.前言 本文承接上一节:GEF入门实例_总结_05_显示一个空白编辑器 在上一节我们为我们的插件添加了一个空白的编辑器,这一节我们将为此编辑器添加内容. 二.GEF的MVC模式 在此只简单总结一下, ...
- GEF入门实例_总结_05_显示一个空白编辑器
一.前言 本文承接上一节:GEF入门实例_总结_04_Eclipse插件启动流程分析 在第三节( GEF入门实例_总结_03_显示菜单和工具栏 ),我们创建了菜单和工具栏. 这一节,我们来实现:点击 ...
- GEF入门实例_总结_04_Eclipse插件启动流程分析
一.前言 本文承接上一节:GEF入门实例_总结_03_显示菜单和工具栏 注意到app目录下的6个类文件. 这6个文件对RCP应用程序而言非常重要,可能我们现在对这几个文件的理解还是云里雾里,这一节我们 ...
- GEF入门实例_总结_03_显示菜单和工具栏
一.前言 本文承接上一节: GEF入门实例_总结_02_新建初始RCP空项目 这一节,我们来给我们的插件加上菜单. 二.基础知识 1.action bar.menubar.coolbar 含义 a ...
- GEF入门实例_总结_02_新建初始RCP空项目
一.前言 本节承接上一节: GEF入门实例_总结_01_教程.源码.开发环境准备 这一节我们来创建一个空的RCP项目. 二.新建RCP项目 1. New 一个 Plug-in Project 2.输入 ...
- ArcGIS for Desktop入门教程_第七章_使用ArcGIS进行空间分析 - ArcGIS知乎-新一代ArcGIS问答社区
原文:ArcGIS for Desktop入门教程_第七章_使用ArcGIS进行空间分析 - ArcGIS知乎-新一代ArcGIS问答社区 1 使用ArcGIS进行空间分析 1.1 GIS分析基础 G ...
随机推荐
- 闪讯 开启wifi教程
这是我自己试了几次之后发现的,也不是什么技术活. 首先说下,我的比较是小米pro笔记本,一般笔记本都是自带wifi功能的.如果要开wifi的话,必须是用网线连接才可以,通过wifi连接网络就不能开移动 ...
- scrollWidth、clientWidth 和 offsetWidth
scrollWidth:对象的实际内容宽度,不包括边线宽度,会随对象中内容超过可视区而变大. clientWidth:对象内容的可视区的宽度,不包括边线宽度,会随对象显示大小的变化而变化. offse ...
- Yii 数据库重连告别General error: 2006 MySQL server has gone away
General error: 2006 MySQL server has gone away 错误原因 制造错误 解决办法 最新办法 错误原因 Mysql has gone away MySQL 服务 ...
- OptimalSolution(8)--位运算
一.不用额外变量交换两个整数的值 如果给定整数a和b,用以下三行代码即可交换a和b的值.a = a ^ b; b = a ^ b; a = a ^ b; a = a ^ b :假设a异或b的结果记为c ...
- SVM详细笔记及总结
本文精品,如有疑问欢迎留言or微信咨询:523331232
- 机器学习笔记(一)· 感知机算法 · 原理篇
这篇学习笔记强调几何直觉,同时也注重感知机算法内部的动机.限于篇幅,这里仅仅讨论了感知机的一般情形.损失函数的引入.工作原理.关于感知机的对偶形式和核感知机,会专门写另外一篇文章.关于感知机的实现代码 ...
- DB2中的MQT优化机制详解和实践
MQT :物化查询表.是以一次查询的结果为基础 定义创建的表(实表),以量取胜(特别是在百万,千万级别的量,效果更显著),可以更快的查询到我们需要的结果.MQT有两种类型,一种是系统维护的MQT , ...
- CentOS6.5下安装JDK1.7+MYSQL5.5+TOMCAT7+nginx1.7.5环境安装文档
----------------CentOS6.5下安装JDK1.7+MYSQL5.5+TOMCAT7+nginx1.7.5环境安装文档----------------------- [JDK1.7安 ...
- u检验粗浅理解
假设检验是以小概率事件,在一次实验中是不可能发生为前提(事实上是有可能发生的,但不是这样说的话,就落入一个圈,不能继续玩了),来否认原假设. u检验的定义: 已知从正态母体N(u,σ2)中抽得容量为n ...
- Django学习day4——视图和URL配置
创建一个简单的hello world 在day3中我们第一次运行了服务器,里面是一个django的欢迎页面,那是因为我们没有配置URL和视图,django在底层会自动跳转这个页面上 我们在mysite ...