rus的t数据结构

变量与可变性

  • 声明变量使用let关键字
  • 默认情况,变量是不可变量(immutable)
let a = 1;
a = 3;          // 编译错误,不能两次赋值给不可变量
  • 声明变量时候,在变量前面加上mut,就可以使变量可以变。
let mut a = 1;
a = 3;          // 编译通过

变量与常量

  • 常量(constant),常量在绑定值以后也是不可变的,但是他与不可变的变量有很多区别:
  1. 不可以使用mut,常量永远都是不可变得
  2. 声明常量使用const关键字,它的类型必须被标注
  3. 常量可以在任何作用域内进行声明,包括全局作用域
  4. 常量只可以绑定到常量表达式,无法绑定到函数的调用结果或只能在运行时才能计算出的值
  • 在程序运行期间,常量在声明的作用域内一直有效
  • 命名规范:rust里常量使用全大写字母,每个单词直接用下划线分开,例如:
const MAX_POINTS:u32 = 100_000;

shadowing(隐藏)

  • 可以使用相同的名字声明新的变量,新的变量就会shadow(隐藏)之前声明的同名变量。
  1. 在后续的代码中这个变量名代表的就是新的变量
let a = 2;
let a = a + 1;          // shadow
  • shadow和吧变量标记为mut是不一样的
  1. 如果不适用let关键字,那么重新给非mut的变量赋值会导致编译时错误
  2. 而使用let声明的同名新变量,也是不可以变得
  3. 使用let声明的同名星变量,它的类型可以之前不同
    let a = 1;
    a = a + 1;      // 编译报错 1
    let a = "fff";  // 3

数据类型

  • 标量和复合类型
  • rust是静态编译语音,在编译时必须知道所有变量的类型
  1. 基于使用的值,编译器通常能够推断出他的具体类型
  2. 但如果可能的类型比较多(例如吧string转为整数的parse方法),就必须添加类型标注,否则编译就会报错
let guess: u32 = "32".parse().expect("not a number");

整数类型

  • 整数类型没有小数部分
  • 例如u32就是一个无符号的整数类型,占据32位的空间
  • 无符号整数类型以u开头
  • 有符合整数类型以i开头
  • rust的整数类型列表如图:
lengthsignedunsigned
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
archisizeusize
  1. 每种都分i和u,以及固定的为数
  2. 有符号范围:-(2n-1)到2n-1
  3. 无符号范围:0到2^n-1

isize和usize类型

  • isize和usize类型的位数有程序运行的计算机的架构所决定:
  1. 如果是64位计算机,那就是64位的
  • 使用isize和usize的主要场景是对某种集合进行索引操作。

整数字面值

  • 除了byte类型外,所有的数值字面值都允许使用类型后缀。
  • 如果你不太清楚应该使用那种类型,可以使用rust相应的默认类型
  • 整数的默认类型及时i32
  1. 总体上来说速度很快,即使64位系统中
number literalsexample
decimal98_222
hex0xff
octal0o77
binary0b1111_0000
byte(u8 only)b’A’

整数溢出

  • 例如:u8的范围是0-255,如果你把一个u8变量的值设为256,那么:
  • 调试模式下编译:rust会检查整数溢出,如果发生溢出,程序在运行就会panic
  • 发布模式下(–release)编译:rust不会检查可能导致panic的整数溢出
  1. 如果溢出发生:rust会执行“环绕”操作:256变成0,257变成1
  2. 但是程序不会panic

浮点类型

  • rust有两种基础的浮点类型,也就是含有小数部分的类型
  1. f32 32位,单精度
  2. f64 64位,双精度
  • rust的浮点类型使用了IEEE-754标准来表述
  • f64是默认类型,因为在现代CPU上的f64和f32的速度差不多,而且精度更高。
let a = 2.0;        // f64
let b:f32 = 2.0;    // f32
let c:f64 = 4.0;    // f64

数值操作

  • 加减乘除余等
let sum = 9 + 2;
let defference = 9.7 - 4.3;
let product = 4 * 33;
let quotient = 55.6 / 44.2;
let reminder 44 % 4;

布尔类型

  • rust的布尔类型也有两个值:true和false
  • 一个字节大小
  • 符号是bool
let t = true;
let f: bool = false;

字符类型

  • rust语音中char类型被用来描述语音中最基础的单个字符。
  • 字符类型的字面值使用单引号
  • 占用4字节大小
  • 是Unicode标量值,可以表示比ASCII多得多的字符内容:拼音、中日韩文、零长度空白字符、emoji表情等。
  1. U+0000到U+D7ff
  2. U+E000到U+10FFFF
  • 但是Unicode中并没有“字符”的概念,所以直接上认为的字符与rust中的概念并不相符
let x = 'x';
let y: char = 'y';
let z = '✌';

复合类型

  • 复合类型可以将多个值放在同一个类型里。
  • rust提供了两种基础的复合类型:元组(tuple)、数组

tuple

  • tuple可以将多个类型的多个值放在一个类型里
  • tuple的长度是固定的:一旦声明就无法改变

创建tuple

  • 在小括号里,将值用逗号分开
  • tuple中的每个位置都对应一个类型,tuple中个元素的类型不必相同
let tup:(i32, f64, u8) = (599, 8.4, 3);
println!("{}, {}, {}", tup.0, tup.1, tup.2);

获取tuple的元素值

  • 可以使用模式匹配来解构(destructure)一个tuple来获取元素的值
let tup:(i32, f64, u8) = (599, 8.4, 3);
let (x, y, z) = tup;
println!("{}, {}, {}", x, y, z);

访问tuple的元素

  • 在tuple变量使用点标记法,后接元素的索引号

数组

  • 数组也可以将多个值放在一个类型里
  • 数组中每个元素的类型必须相同
  • 数组的长度也是固定的

声明一个数组

  • 在中括号里,各值用逗号分开
let a = [2, 3, 4, 5];

数组的用处

  • 如果想让你的数据放在stack(栈)上而不是heap(堆)上,或者想保证有固定数量的元素,这时使用数组更有好处
  • 数组没有vector灵活
  1. vector和数组类似,它由标准库提供
  2. vector的长度可以改变
  3. 如果你不确定应该用数组还是vector,那么估计你应该用vector

数组的类型

  • 数组的类型以这种形式表示:[类型;长度]
let a:[i32;5] = [1, 3, 4, 5, 6];

另一种声明数组的方法

  • 如果数组的每个元素都是相同,那么可以在
  1. 在中括号里指定初始值
  2. 然后是一个";"
  3. 最后是数组的长度
let a = [3; 4];
let a = [3, 3, 3, 3];

访问数组的元素

  • 数组是stack上分配的单个块的内存
  • 可以使用索引来访问数组的元素
  • 如果访问的索引超过了数组的范围,那么
  1. 编译会通过
  2. 运行会报错(runtime是会panic)
  3. rust不允许其继续访问相应地址的内存

函数

  • 声明函数使用fn关键字
  • 依照惯例,针对函数和变量名,rust使用snake case命名规范:
  1. 所有的字母都是小写的,单词之间使用下划线分开

函数的参数

  • parameters, arguments
fn main() {
    test_fun(888);
}
fn test_fun(x: i32){
    println!("the value of x is:{}", x);
}

函数体中的语句与表达式

  • 函数体有一系列语句组成,可选的由一个表达式结束
  • rust是一个基于表达式的语言
  • 语句是执行一些动作的指令
  • 表达式会计算产生一个值
  • 函数的定义也是一个语句
  • 语句没有返回值,所有不可以使用let将一个语句赋给一个变量
fn main() {
    let x = 3;
    let y = {
        let x = 1;
        x + 3
    };      // 表达式
    //  let y = {
    //     let x = 1;
    //     x + 3;
    // };      // 语句 空的()
    println!("the value of y is:{}", y);
    println!("the value of x is:{}", x);
}

函数的返回值

  • 在->符号后边声明函数返回值的类型,但是不可以为返回值命名
  • 在rust里面,返回值就是函数体里面最后一个表达式的值
  • 若想提前返回,需要使用return关键字,并指定一个值
  • 大多数函数都是默认使用最后一个表达式作为返回值
fn add_val(x: i32)-> i32 {
    x + 5           // 不能加分后 ";"
}
fn main() {
    let x = add_val(4);
    println!("the value of x is:{}", x)
}

if表达式

  • if表达式允许您根据条件来执行不同的代码分支
  • 这个条件必须是bool类型
  • if表达式中,与条件相关联的代码块就叫做分支(arm)
  • 可选的,在后边可以加上一个else表达式
fn main(){
    let num = 3;
    if num > 4 {        // 必须是bool类型
        println!("conditiion was true");
    }else{
        println!("conditiion was false");
    }
}

使用else if 处理多重条件

  • 但如果使用了多与一个else if,那么最好使用match来重构代码
fn main(){
    let condition = true;
    // if else 返回的值的类型必须相同
    let num = if condition { 5 } else { 6 };
    println!("the value of number is:{}", num);
}

rust的循环

  • rust提供了3种循环:loop,while和for

loop循环

  • loop关键字告诉rust反复的执行一块代码,直到停为止
fn main(){
    let mut conunter = 0;
    let result = loop {
        conunter += 1;
        if conunter == 10 {
            break conunter * 2;     // 分号,可以要可以不要
        };              // 分号,可以要可以不要
    };
    println!("the result is:{}", result);
}

while条件循环

  • 另外一种常见的循环模式是每次执行循环体之前都判断一次条件
  • while条件循环为这种模式而生
fn main(){
    let mut number =3;
    while number != 0 {
        println!("{}", number);
        number -= 1;
    };          // 分号 可要可不要
    println!("finish")
}

使用for循环遍历集合

  • 可以使用while或loop来遍历集合,但是易错且低效
  • 可以使用for循环更简洁紧凑,它可以针对集合中的每个元素来执行一下代码
fn main(){
    let a = [2, 4, 1, 4, 5];
    for ele in a.iter() {       // 数组迭代器
        println!("the value is:{}", ele);
    }
}
  • 由于for循环的安全、简洁性,所以它在rust里用的最多

range

  • 标准库提供
  • 指定一个开始数字或一个结束数字,range可以生成他们之间的数字(不包含结束)
  • rev方法可以反转range
fn main(){
    for num in (1..=5).rev(){
        println!("{}", num);
    }
    println!("finish")
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值