^(* ̄(oo) ̄)^

  • 首页
  • 博客
  • 文档
  • 网盘
  • 仓库
  • 简介
Keep Learning
  1. 首页
  2. 文档
  3. 正文

Rust Basic 3 - Variables And Functions

2023年4月7日 747点热度

Variables and Mutability

默认情况下,变量是不可变的。在没有使用mut的情况下,若重复修改变量的值会产生error[E0384]: cannot assign twice to immutable variable x。

Constants

同不可能变量相同,常量的值也不可修改。但是常量不允许使用mut,常量不仅在默认情况下是不可变的--它们始终是不可变的的。定义常量使用const关键字,而且必须在初始化时赋值,值只能是一个常量表达式。

const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

Rust 的常量命名约定是全部使用大写字母,单词之间有下划线。

Shadowing

声明一个同名新变量,覆盖先前的变量。

shadowing和使用mut存在两点不同,使用mut是不会改变变量类型,而使用let实际上是创建了一个同名新变量。且此变量可以不为之前的类型。

如下第一个spaces变量是字符串类型,第二个spaces变量是数字类型。使用let可以减少重新起名。但用mut无法做到这种事。

    let spaces = "   ";
    let spaces = spaces.len();

运行时错误:mismatched types

    let mut spaces = "   ";
    spaces = spaces.len();

Data Types

rust 中每个值都有特定的数据类型。scalar and compound。

rust 是一种静态类型语言,因此它必须在编译时知道所有变量的类型。编译器通常会根据值和使用它的方式来推断值的类型。但在存在多种类型的情况下,需指明具体类型。例如数字类型。

    let guess: u32 = "42".parse().expect("Not a number!");

scalar

Scalar 用于表示单个值。rust中主要有四种类型:integers,floating-point numbers, Booleans, 以及characters。

integers

整数是没有小数部分的数字。i开头的为有符号的整数,u开头的为无符号的整数。

Length Signed Unsigned
8-bits i8 u8
16-bits i16 u16
32-bits i32 u32
64-bits i64 u64
128-bits i128 u128
arch isize usize

当需要表示有符号数的时候,需使用Signed,有符号数使用二进制补码来存储(原码取反+1)。二者的取值范围如下:

进制 示例
Decimal 98_222
Hex 0xff
Octal 0o77
Binary 0b1111_0000
Byte (u8 only) b'A'

注:数字间可以使用_为视觉分隔符。1_000的值等同于1000。

overflow

当使用u8类型时,值的范围为0-255,若将值赋为256,不管release还是debug都会报错 literal out of range for u8。

但是要是换成此种写法,在debug mode下会产生不变,而在 release mode下,不会检查整数溢出,若发生溢出,Rust执行二进制补码进行包装,当值为u8类型时,256会变成0,257会变成1。程序不会panic,但是值可能不是期望值。

处理显式溢出,可以使用标准库的以下方法 rust doc:

  1. wrapping_add 当overflow时,会自动回到最小值,结果和使用release相同,但是使Wrapping包装类可以在debug模式下使用,同时避免出现不可预期的结果。

  1. 使用checked_add方法。会在溢出时返回None,方便定位是否产生溢出。

3,使用overflowing_add。此方法会返回一个结果和一个布尔值来定位是否溢出,相较于wrapping_add多一个是否溢出的标记。

  1. 使用saturating_add。越界时数值为临界点的值。

Floating-Point Types

浮点数是带小数点的数字。Rust有f32和f64两种。浮点数都是有符号数,且默认为f64。

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

Numeric Operations

rust数字类型支持所有基本数学运算,整数除法时,结果取最接近0的整数。

The Boolean Type

布尔类型一个字节,有true和false两种值。可以隐式和显式声明。

fn main() {
    let t = true;
​
    let f: bool = false; // with explicit type annotation
}

The Character Type

char是rust最原始的类型。 字符型使用单引号指定文字,而非双引号。同时大小为4个字节,表示一个Unicode标量值,故而字符型不仅可以表示ASCII,也可以表示带音调的字母、中文、日文、韩文字符、emoji以及零宽空格。

Unicode标量值的范围 U+0000 到 U+D7FF 和 U+E000 到 U+10FFFF(含)。字符于rust中比较特殊。

compound Types

复合类型可以将多个值组合成一个类型。rust中有两种基本的符合类型:元组(tuples)和数组(arrays)。

The Tuple Type

元组是将多个具有多种类型的值组合成一个复合类型的通用方法。固定长度:声明后,它们的大小就不能增加或缩小。若要从元组中取单个值:1.通过模式匹配来解析元组值。 2.通过使用句点(.)后接索引来访问元素(从0开始)。

当一个元组没有任何值,那么它拥有一个特殊的名字-> unit。 这个值及其对应的类型都写作(),表示空值或空返回类型。一般用于函数无返回值时。

fn say_hi() -> () {
    println!("Hi!");
}
​
// 显式返回
fn say_hi() -> () {
    println!("Hi!");
    return ();
}

The Array Type

数组每个元素必须具有相同的类型,Rust中数组具有固定长度。数组中的值在方括号内以逗号分隔。故而当数量固定时数组很有用。vector相较于数组更灵活,可以扩大或缩小大小。

 

Functions

函数的关键字为fn,main函数是所有程序的入口。rust中变量名与函数名都使用蛇形方式来定义:所有字母均小写,并用下划线分隔单词。

带参数的函数

函数签名中必须声明每个参数类型。多个参数之间用逗号隔开。

语句和表达式

语句是执行某些操作但没有返回值的指令。

表达式是计算结果值。

无法做到c语言中的 x=y=6;

表达式可以是语句的一部分:计算结果是表达式,调用函数是表达式,调用宏是表达式,用大括号创建的新作用域块是一个表达式。

同大多数行不同,该x+1行末尾没有分号。表达式不包括结束分号,若在表达式末尾添加分号,就成为了一个语句,就不再返回值。

带返回值的函数

Rust中,函数的返回值和函数体块中最终表达式的值同义。返回值需通过箭头(->)声明它们的类型。可以通过return关键字从函数中提前返回,但更多的函数会隐式返回最后一个表达式。

Control Flow

if Expressions

if 的条件必须是一个bool值,

if在let声明中使用(类似 int x = condition? 1:2)

因为变量必须有单一类型,而 Rust 需要在编译时明确地知道 number变量是什么类型。故if和else表达式结果需为同一类型。

loops

rust循环有三种:loop、while和for。

loop

循环标签必须以单引号开头。多级嵌套循环时,当在内循环中使用外循环的continue和break时。可以通过给外循环指定一个循环标签来实现。

while

条件循环。节省了loop中各种的if,else以及break代码。当条件为true时执行循环。

for

rust中最常用的循环结构。使用for遍历数组时,不需考虑数组的个数。减少了出现错误的可能性。

标签: rust rust-basic
最后更新:2023年4月7日

九州安所如

程序员

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2023 zhu

鲁ICP备2026022547号