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 ...
随机推荐
- mysql字段按逗号,拆分并按条件查找
mysql字段按逗号,拆分并按条件查找 mysql 表结构 CREATE TABLE `subid` ( `id1` varchar(255) DEFAULT NULL, `id2` varchar( ...
- [.Net Core 3.0从入门到精通]1.笔记简介及.Net Core3.0介绍
文章目的:.Net Core 3.0学习笔记整理与分享. 面向人群:有一定基础的C#开发人员或学习人员(C#语法一定要掌握). 笔者水平:中级C#开发攻城狮(水平有限,写的不对的地方希望大家指正). ...
- 回头看 vue-router
回头看 vue-router 复习 我的github iSAM2016 目录 响应路由参数的变化 嵌套路由 函数式导航 路由的命名 示例:切换路由的时候可以修改页面的标题 导航钩子 全局钩子 实例:检 ...
- js控制进度条数据
<style><!-- #time{ width:500px; height: 20px; background: red; border-radius: 10px; } --> ...
- SpringBoot与MybatisPlus整合之SQL分析插件(六)
pom.xml: <dependency> <groupId>p6spy</groupId> <artifactId>p6spy</artifac ...
- 快速学习ggplot2
R语言里面一个比较重要的绘图包——ggplot2,是由Hadley Wickham于2005年创建,于2012年四月进行了重大更新,作者目前的工作是重写代码,简化语法,方便用户开发和使用.ggplot ...
- Python 中的反射方法
一.概述 getattr # 根据字符串为参数,去对象中找与之同名的成员. hasattr # 根据字符串为参数,去判断对象中是否有与之同名的成员. setattr # 根据字符串为参数,动态的设置一 ...
- springboot---发送邮件
1.pom.xml配置 <dependencies> <dependency> <groupId>org.springframework.boot</grou ...
- ubuntu19.10桌面版
一:安装ubuntu卡住,英伟达显卡兼容性问题 解决方法: 将 quite splash --- 改为 quite splash nomodeset 二:从零开始配置ubuntu19.10 sudo ...
- 在虚拟机上的关于Apache(阿帕奇)(5)基于端口访问网站
这篇随笔是基于端口访问网站,和前面两篇文章基于ip和基于域名一起练习效果更好 接下来分别创建三个网站数据目录 输入命令: mkdir -p /home/wwwroot/{8001,8002,800 ...