
^^《榴芒客服系统》是我们工作室开发的在线客服系统欢迎下载试用https://blog.csdn.net/look4liming/article/details/164755808https://blog.csdn.net/look4liming/article/details/164755808Rust是表达式语言。if和switch是语句他们不生成值也不能在表达式中间使用而在Rust中if和match可以生成值。所有可以链式书写的运算符都是左结合的。比较运算符、赋值运算符和范围运算符则根本无法链式书写。如果一个块看起来很像C代码每个地方都有分号那么它就会像C的块一样运行并且其值为()。当块的最后一行不带分号时就以最后这个表达式的值而不是通常的()作为块的值。在Rust中分号是有实际意义的let msg {// let声明分号总是必须的let dandelion_control puffball.open();// 带分号的表达式调用方法丢弃返回值dandelion_control.release_all_seeds(launch_codes);// 无分号的表达式调用方法返回值将存入msgdandelion_control.get_status();};变量名必须以字母或下划线开头并且只能在第一个字母之后包含数字。“字母”是广义的包括希腊字母、带重音的拉丁字符和更多符号也包括中文。不允许使用表情符号。let声明可以在不初始化变量的情况下声明变量因为有时候确实应该在某些控制流结构的中间初始化变量let name;if user.has_nickname() {name user.nickname();} else {name generate_unique_name();user.register(name);}在初始化之前就使用变量是错误的。看这段代码for line in file.lines() {let line line?;}for循环里的这个let声明会创建一个不同类型的、新的变量。第二个定义会在所处代码块的其余部分代替第一个定义这叫作遮蔽shadowing。块还可以包含语法项声明比如fn、struct或use。当在块内声明一个fn时它的作用域是整个块也就是说它可以在这个封闭块内部使用。但是嵌套的fn无法访问恰好在同一作用域内的局部变量或参数。闭包可以看到封闭块作用域内的变量。if表达式示例if condition1 {block1} else if condition2 {block2} else {block_n}每个condition都必须是bool类型的表达式。condition周围不需要圆括号但花括号是必须的。else if块以及最后的else是可选的。match表达式示例match code {0 println!(OK),1 println!(Wires Tangled),2 println!(User Asleep),_ println!(Unrecognized Error {}, code)}match表达式的一般形式如下match value {pattern expr,...}如果expr是一个块可以省略此分支之后的逗号。Rust禁止执行未覆盖所有可能值的match表达式let score match card.rank {Jack 10,Queen 10,Ace 11}; // 错误为穷举所有模式if表达式的所有块都必须生成相同类型的值。match表达式的所有分支都必须具有相同的类型。if let表达式if let pattern expr {block1} else {block2}expr要么匹配pattern运行block1要么运行block2。if let是只有一个模式的match的简写形式match expr {pattern { block1 }_ { block2 }}4种循环表达式while condition {block}while let pattern expr {block}loop {block}for pattern in iterable {block}各种循环都是Rust中的表达式但while循环或for循环的值总是()。可以用loop来编写无限循环。看下面这个for循环for i in 0..20 {println!({}, i);}..运算符会生成一个范围range及具有两个字段start和end的简单结构体。0..20与std::ops::Range {start: 0, end: 20}相同。标准集合都是可迭代的数组和切片也是如此。为了与Rust的移动语义保持一致把值用于for循环会消耗该值let strings: VecString error_messages();for s in strings { // 在这里每个String都会转移给sprintln!({}, s);} // 并在此丢弃println!({} error(s), srings.len()); // 错误使用了已经转移出去的值这可能很不方便补救措施是在循环中访问此集合的引用。循环变量也会变成对集合中每个条目的引用for rs in strings {println!(String {:?} is at address {:p}., *rs, rs);}这里string的类型是VecStringrs的类型是String。遍历可变引用会为每个元素提供一个可变引用for rs in mut strings { // rs的类型是mut Stringrs.push(\n); // 为每个字符串添加一个换行}break表达式会推出所在循环。break只能用在循环中不能用在match表达式中这与C系语言中的switch语句不同。在loop循环体中可以在break后面跟一个表达式该表达式的值会成为此loop的值continue表达式会跳转到循环的下一次迭代。循环可以带有生命周期标签search: // 生命周期标签for room in apartment {for spot in room.hiding_spots() {if spot.contains(keys) {break search;}}}break可以同时具有标签和值表达式// 找到此系列中的第一个完全平方数的平方根let spart outer: loop {let n next_number();for i in 1.. {let square i * i;if square n {break outer i; // 找到了平方根跳出最外层循环把i给spart}if square n {break;}}};return表达式会退出当前函数并向调用者返回值。不带值的return是return ()的简写fn f() {return; // 返回()}函数调用与方法调用let x gcd(1302, 462); // 函数调用let room player.location(); // 方法调用在上面的代码中player可能是Player、Player类型的引用也可能是BoxPlayer或RcPlayer类型的智能指针因为Rust的.运算符会根据需要自动对player解引用或接入对它的引用。普通方法会在值上调用如my_vec.len()类型关联函数会在类型是调用如Vec::new()在函数调用或方法调用中泛型类型的常用语法VecT是不起作用的return Veci32::with_capacity(1000); // 错误let ramp (0..n).collectVeci32(); // 同样错误在表达式中是小于运算符Rust编译期建议用::T代替Treturn Vec::i32::with_capacity(1000);let ramp (0..n).collect::Veci32();或者删掉类型参数让Rust来推断它们return Vec::with_capacity(1000);let ramp: Veci32 (0..n).collect();字段与元素game.black_pawns // 结构体字段coords.1 // 元组元素如果.左边的值是引用或智能指针类型那么它就会像方法调用一样自动解引用。方括号会访问数组、切片或向量的元素pieces[i] // 数组元素方括号左侧的值也会自动解引用。..运算符允许省略任何操作数.. // RangeFulla.. // RangeFrom {start: a}..b // RangeTo {end: b}a..b // Range {start: a, end: b}后两种是排除结束值或半开放的。例如范围0..3包括数值0、1和2但不包括3。..运算符会生成包含结束值或封闭的范围..b // RangeToInclusive {end: b}a..b // RangeInclusive::new(a, b)例如范围0..3包括数值0、1、2和3。一元*运算符用于访问引用所指向的值。看下面的程序let padovan: Vecu64 compute_padovan_sequence(n);for elem in padovan {draw_triangle(turtle, *elem);}elem的类型是u64因此*elem为u64。一元-运算符会对一个数取负它支持除无符号整数之外的所有数值类型。没有一元运算符%取余运算符既能用于整数也能用于浮点数。Rust支持C系语言中的整数位运算符、|、^、和。但是Rust会使用!而不是~表示按位非。移位总是对有符号整数类型进行符号扩展对无符号数进行零扩展。由于Rust支持无符号数所以它不需要这样的无符号移位运算符。Rust不支持链式赋值不能编写ab3来将3同时赋给a和b。Rust没有自增运算符和自减运算符--。将一种类型转换成另一种类型需要显式转换let x 17; // x是i32的let index x as usize; // 通过as关键字将i32转换成usize闭包通常由一个参数列表组成在两条竖线之间列出后跟一个表达式let is_even |x| x % 2 0;如果确实指定了返回类型那么为了语法的完整性闭包的主体必须是一个块let is_even |x u64| - bool x % 2 0; // 错误let is_even |x u64| - bool { x % 2 0; } // 正确调用闭包和调用函数的语法是一样的is_even(14);^^《榴芒客服系统》是我们工作室开发的在线客服系统欢迎下载试用https://blog.csdn.net/look4liming/article/details/164755808https://blog.csdn.net/look4liming/article/details/164755808