从零开始的RUST生活 二

本文介绍了Rust编程语言中的核心概念,包括变量的可变性,常量的区别,变量的隐藏(shadowing)。深入探讨了各种数据类型,如整数、浮点数、布尔值、字符、元组和数组。详细阐述了函数的使用,包括参数、返回值以及控制流结构,如if表达式、循环和注释。此外,还提供了若干编程作业以巩固所学知识。
摘要由CSDN通过智能技术生成

第二章 RUST通用编程概念



前言

官方文档有一个猜数游戏,喜欢的可以去试试,本篇直接进入主题。


一、变量与可变性

rust中的变量默认是不可变的。

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

输出报错:
请添加图片描述意思是不可对不可变变量进行二次赋值。可以在声明的变量前加mut关键字使其可变。

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

请添加图片描述


变量与常量之间的不同

1、绑定到常量上的值无法被其他代码修改。
2、不能用mut关键字修饰一个常量。
3、使用const关键字来声明常量而不是let。
4、常量可以被声明在任何作用域中,包括全局作用域。
5、只能将常量绑定到一个常量表达式上,而无法将一个函数的返回值,或其他需要在运行时计算的值绑定到常量上。

const MAX_POINTS:u32 = 100_000;

6、约定俗成的使用以下划线分割的全大写字母来命名一个常量,并在数值中可以插入下划线提高可读性。


隐藏shadow

先看代码

fn main() {
    let x = 5;
    let x = x + 1;
    let x = x + 2;
println!("x的值是{}",x);
}

请添加图片描述
在rust世界中,一个新声明的变量可以覆盖掉旧的同名变量,这种现象,叫做第一个变量被第二个变量隐藏了。代表之后使用这个名称时,都是指向第二个变量。可重复隐藏。
对比mut理解,x变量不可变但可通过隐藏创建出新的变量,并且可以同时改变原来的类型。

(输入的空格存储为一个独立的值)
fn main() {
    let spaces = "  ";
    let spaces = spaces.len();
println!("变量的值是{}",spaces);
}

请添加图片描述

不需要做出诸如spaces_str和spaces_num之类的区分。用mut会报错。

fn main() {
    let mut spaces = "  ";
    spaces = spaces.len();
println!("变量的值是{}",spaces);
}

请添加图片描述拒绝修改类型。


二、数据类型

rust是静态类型语言,它在编译过程中需要知道所有变量的具体类型。编译器会默认给变量添加类型,当编译器识别不出来时就需要手动添加了。


标量类型

标量类型是单个值类型的统称,共有四个基础的标量类型。
整数、浮点数、布尔值及字符。


整数:

1、指的是没有小数部分的数字。
2、符号指的是正负。
3、不声明默认为i32。
4、isize与usize由计算机架构决定,32或64等。
5、i8能存储-128~127之间的所有整数,u8能存储0-255之间的所有整数。就是2的8次方减1,256-1=255。

长度有符号无符号
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
archisizeusize

6、可以使用下表列出的所有方式在代码中书写整数字面量,除了Byte,其余所有字面量都可以使用类型后缀,比如57u8,代表一个使用了u8类型的整数57。

整数字面量翻译示例
Decimal十进制98_222
Hex十六进制0xff
Octal八进制0o77
Binary二进制0b1111_0000
Byte(u8 only)字节b’A’

整数溢出:
当一个u8类型的变量,它可以存储从0到255的数字,当尝试将该变量修改为超过范围的值(256),就会发生整数溢出。

fn main() {
    let x:u8 = 256;
    
println!("变量的值是{}",x);
}

请添加图片描述

新版本的release一样触发了报错,可以自行尝试,书上说的是会环绕为类型的最小值,256变成0,257变成1。
希望显式地进行环绕行为,可以使用标准库中的类型Wrapping。


浮点数类型

1、指小数。
2、默认为f64。
3、Rust的浮点数使用了IEEE-754标准来进行表述,f32对应单精度浮点数,f64对应双精度浮点数。

fn main(){
    let x = 2.0;//f64
    let y:f32 = 3.0;//f32
}

数值运算

加减乘除和取余。

fn main() {
    let sum = 5 + 10;
    let difference = 95.5-4.3;
    let product = 4 * 30;
    let quotient = 56.7 / 32.2;
    let remainder = 43 % 5;   
    println!("加{},减{},乘{},除{},取余{}",sum,difference,product,quotient,remainder);
}

请添加图片描述

布尔类型

1、true与false。
2、占据1个字节大小。
3、使用bool表示一个布尔类型。

let f:bool = false;

4、主要作用是在if表达式内作为条件使用。


字符类型

1、char类型被用于描述最基础的单个字符。
2、char类型使用单引号指定,不同于字符串使用双引号指定。
3、char类型占4字节,是一个Unicode标量值,可以表示拼音字母、中文、日韩文、空白字符甚至emoji表情。(U+0000~U+D7FF以及从U+E000到U+10FFFF的所有值)


复合类型

1、复合类型可以将多个不同类型组合为一个类型。
2、rust内置的基础复合类型:元组tuple和数组array。


元组类型

1、可以将不同类型的多个值组合进一个复合类型。
2、元组具有固定长度,无法在声明后增减其中的元素数量。

let tup: (i32,f64,u8) = (500,6.4,1);

3、元组也被视作一个单独的复合元素。
4、可以使用模式匹配的方法来解构元组,从元组中获得单个的值。

fn main() {
    let tup = (500,6.4,1);
    let (x,y,z) = tup;  
    println!("x={},y={},z={}",x,y,z);
}

请添加图片描述5、除了解构,还可以通过索引并使用点号(.)来访问元组中的值。

fn main() {
    let a: (i32,f64,u8) = (500,6.4,1);
    //创建元组a
    let x = a.0;
    //通过索引访问元组的各个元素,并绑定它们的值到新的变量上。
    let y = a.1;
    let z = a.2;
    println!("x={},y={},z={}",x,y,z);
}

请添加图片描述


数组类型

1、与元组不同,数组中的元素的类型必须是相同的
2、具有固定长度,不可变。

let a:[i32;5] = [1,2,3,4,5];

tips:动态数组vector允许调整数组长度。详情第七章,现在仅做了解。
语法糖:

let a = [3;5];
//等价于
let a = [3,3,3,3,3];

访问数组的元素

let a = [1,2,3,4];
let first = a[0];

非法的数组元素访问

fn main() {
    let a = [ 1,2,3,4,5];
    let index = 10;
    let element = a[index];
    println!("element的值为{}",element);
}

这段代码可以通过编译,但是实际运行会报错并崩溃退出。当通过索引来访问一个元素时,rust会进行检查,当超出了当前长度,则会发生panic(第8章)。
请添加图片描述


三、函数

1、rust采用蛇形命名法,只是用小写字母命名函数,可使用下划线分割单词。
2、函数定义以fn关键字并紧随函数名与一对圆括号,还有一对花括号用于标识函数体开始和结尾的地方。

fn abc(){}

3、rust不关心在何处定义函数,只要定义对于使用区域可见。


函数参数

1、可以在函数声明中定义参数,作为特殊变量视为函数签名的一部分。
2、必须显式声明每个参数的类型。

fn main() {
	abc(5,6);
}
fn abc(x:i32,y:i32){
	println!("x={}",x);
	println!("y={}",y);
}

请添加图片描述


函数体中的语句和表达式

1、rust是一门基于表达式的语言,它将语句与表达式区别为两个不同的概念。
2、语句指的是执行操作但不返回值得指令,表达式是指进行计算并产生一个值作为结果的指令。看下列代码增强理解。

fn main(){
    let y = 6;
    //使用let关键字创建变量并绑定值,let y = 6;就是一条语句。
}
//
fn main(){
    let x = (let y = 6);
}
//该程序会报错,语句不会返回值,x没有可以绑定的东西,所以不能将一条let语句赋值给另一个变量。
fn main() {
	let x = 5;
	let y = {
		let x = 3;
		x + 1
	};//该分号位置需要注意,x+1后未加分号。
	println!("x={}",x);
	println!("y={}",y);
}

3、表达式会计算出某个值作为结果。在rust中编写的大部分代码都会是表达式。
4、表达式本身也可以作为语句的一部分。let y = 6;中,字面量6就是表达式,它返回6作为自己的计算结果。
5、5+6是表达式,调用函数是表达式,调用宏是表达式,花括号也是表达式。
6、可由分号位置简单判断是否是语句或表达式。


函数的返回值

1、函数可以向调用它的代码返回值,可以不用对这个值命名,但需要在箭头符号后面声明它的类型。
2、在rust中,函数的返回值等同于函数最后一个表达式的值,可以使用return关键字并指定一个值来提前从函数中返回,大多数函数都隐式地返回了最后的表达式。

fn five() -> i32{//指定类型
	5
}//该函数没有任何其他的函数调用、宏调用,let语句,但也是一个有效的函数。
fn main(){
	let x = five();
	println!("x={}",x);
}
//x=5
fn main(){
	let x = plus_one(5);
	println!("x={}",x);
}
fn plus_one(x:i32) -> i32{
	x+1//这里不能加分号,加分号默认为语句,返回空元组,与i32产生矛盾
}
//x=6

四、注释

1、常用//,/**/也行。
tips:13章会介绍///和//!


五、控制流

在rust中用来控制程序执行流的结构主要就是if表达式与循环表达式。


if 表达式

1、if…else,如果…则,假如满足条件,则运行这段代码,否则运行另一个代码。

fn main(){
	let number = 3;
	if number < 5 {//条件
		println!("true");//分支(arm)
	}else{//如果没有提供else,且条件判断为假,则继续向下执行代码。
		println!{"false"};
	}
}
//true

2、代码中的条件表达式必须产生一个bool类型的值,否则会触发编译错误。rust不会自动尝试将非布尔类型的值转换为布尔类型。(不同于Ruby与JavaScript)
3、所有if分支可能返回的类型必须是同一类型,否则会报错。


使用else if 实现多重条件判断

if…else if…else if…else
多个条件。因为rust中有更强大的语法match,不做过多描述。


在let语句中使用if

fn main(){
	let y = true;
	let x = if y{
		5
	}else{
		6
	};
		println!{"x={}",x};
}
//x=5

使用循环重复执行代码


使用loop重复执行代码

1、loop无限循环。
2、通过break终止循环。


从loop循环中返回值

fn main(){
	let mut counter = 0;
	let result = loop {
		counter += 1;//相加并赋值
		if counter == 10 {//相等性比较
			break counter * 2;
		}
	};
	println!("result={}",result);
}
//result=20

while 循环

1、条件循环,每次循环都判断一次条件。

fn main(){
	let mut number = 3;
	while number != 0{//不等于
		println!("{}!",number);
		number = number - 1;
		}
	println!("结束");
}
//3!2!1!结束

使用for来循环遍历集合

1、更安全简单快捷,

fn main(){
	for number in (1..4).rev(){//rev反转
		println!("{}!",number);
	}
	println!("结束");
}
//结果与while相同

作业

1、摄氏温度与华氏温度的互相转换。

2、生成一个n阶的斐波那锲数列。

3、打印圣诞颂歌The Twelve Days of Christmas的歌词,并利用循环处理其中重复的内容。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值