校园网站建设年度总结,宠物网站项目,临沂seo全网营销,网站建设合同服务响应时间变量绑定#xff08;声明变量#xff09;
let 变量名: 类型 变量值;
let 变量名 变量值[类型];
// 整型 默认 i32#xff1b;浮点 默认 f64所有的 let 绑定都必须尾接;#xff0c;代码块也不例外。
mut 可以通过重新声明的方式来改变变量类型 可以下划线改善数字的可读…变量绑定声明变量
let 变量名: 类型 变量值;
let 变量名 变量值[类型];
// 整型 默认 i32浮点 默认 f64所有的 let 绑定都必须尾接;代码块也不例外。
mut 可以通过重新声明的方式来改变变量类型 可以下划线改善数字的可读性 声明常量 const / static 除了string字面量其他类型的 static 必须显示声明类型 static str 原生类型 primitives
标量类型 scalar type
* 有符号整数signed integers
i8、i16、i32、i64、i128 和 isize指针宽度
* 无符号整数unsigned integers
u8、u16、u32、u64、u128 和 usize指针宽度
* 浮点数floating point
f32、f64
* 字符char
char 单个 Unicode 字符如 ‘a’‘α’ 和 ‘∞’每个都是 4 字节
* 布尔型bool
bool 只能是 true 或 false
* 单元类型unit type
()。其唯一可能的值就是 () 这个空元组 尽管单元类型的值是个元组它却并不被认为是复合类型因为并不包含多个值。 复合类型 compound type
数组array
如 [1, 2, 3]
类型标记 [类型; 长度]
切片 slice 长度不定 类型标记 [T] slice 可以用来借用数组的一部分
slice[0]
slice.len()数组可以自动被借用成为 slice 数组名 元组tuple
如 (1, true) 元组可以解构赋值
let foo Foo { x: (1, 2), y: 3 };
let Foo { x: (a, b), y } foo;可以通过下标访问 元组名.0
单个元素的元组需要补一个逗号, 与带括号的字面量区分开
元组可以嵌套 函数可以使用元组来返回多个值 自定义类型
结构体 struct
元组结构体 相当于 具名元组C 语言风格结构体
struct 结构名 {属性名1: 类型,属性名2: 类型,
}单元结构体unit struct 不带字段在泛型中很有用
.. 解构结构体只会添加还没有设置的元素
let point: Point Point { x: 10.3, y: 0.4 };
let bottom_right Point { x: 5.2, ..point };
// (5.2, 0.4)let Point { x: left_edge, y: top_edge } point;
// left_edge top_edge 分别取到 xy 的值
let Pair(integer, decimal) Pair(1, 0.1);枚举 enum
enum WebEvent {// 一个 enum 可以是单元结构体称为 unit-like 或 unitPageLoad,PageUnload,// 或者一个元组结构体KeyPress(char),Paste(String),// 或者一个普通的结构体。Click { x: i64, y: i64 }
}访问枚举值
// 方法一
WebEvent::PageLoad// 方法二
use WebEvent::{PageLoad};
// or
// use WebEvent::*;
let xxx PageLoad; // 等价于 WebEvent::PageLoad分支判断枚举
match event {WebEvent::PageLoad println!(page loaded),WebEvent::PageUnload println!(page unloaded),// 从 enum 里解构出 c。WebEvent::KeyPress(c) println!(pressed {}., c),WebEvent::Paste(s) println!(pasted \{}\., s),// 把 Click 解构给 x and y。WebEvent::Click { x, y } {println!(clicked at x{}, y{}., x, y);},
}枚举默认值从0开始 显示赋值
enum Color {Red 0xff0000,Green 0x00ff00,Blue 0x0000ff,
}使用时可进行类型转化来访问值
Color::Red as i32enum 的一个常见用法就是创建链表 类型系统
类型转换 Rust 不提供原生类型之间的隐式类型转换 通过 as 显示的类型转化
someVar as u32当把任何类型转换为无符号类型 T 时(数据范围不匹配)会不断加上或减去 (std::T::MAX 1)直到值位于新类型 T 的范围内。 实际实现是从最低有效位LSBleast significant bits开始保留 8 位然后剩余位置直到最高有效位MSBmost significant bit都被抛弃。 当把无符号类型转化为等长的有符号类型最高位为1时标记为负数详情查阅 计算机原理-补码相关内容 #![allow(overflowing_literals)] 不显示类型转换产生的溢出警告。 rust 1.45 以后将浮点数转化为无符号整数超出上限 会直接转化为最大值低于下限 会直接取 0。 因为若按上述方法转化会让结果难以预料。 但依然可以使用 .to_int_unchecked::u8() 维持原来的转化方式 字面量
可通过后缀方式声明其类型 整数 默认 u32 浮点数 默认 f64
类型推断
可以根据赋予的值来推断类型 减少显示声明类型 Vec 可以通过传入数据的类型 确定其类型 别名 type
可以使用 type 对类型进行别名。 但必须采用大驼峰的命名方式
type Inch u64;可以使用 #[allow(non_camel_case_types)] 屏蔽此规则 类型转化方法
最一般的转换会用到 From 和 Into 两个 trait。
From 与 Into
impl Fromi32 for Number {fn from(item: i32) - Self {Number { value: item }}
}
let num Number::from(30);Into trait 就是把 From trait 倒过来而已 已经写 From 后便不再需要写 Into 了 同into的类型也不需要注明
let int 5;
let num: Number int.into();TryFrom 与 TryInto
use std::convert::TryFrom;
use std::convert::TryInto;TryFrom 和 TryInto trait 用于易出错的转换也正因如此其返回值是 Result 型。
impl TryFromi32 for EvenNumber {type Error ();fn try_from(value: i32) - ResultSelf, Self::Error {if value % 2 0 {Ok(EvenNumber(value))} else {Err(())}}
}Ok() Err()
let result: ResultEvenNumber, () EvenNumber::try_from(8)
let result: ResultEvenNumber, () 8i32.try_into();ToString 与 FromStr
实现 fmt::Display trait它会自动提供 ToString
调用 ToString
circle.to_string()use std::string::ToString;
impl ToString for Circle {fn to_string(self) - String {format!(Circle of radius {:?}, self.radius)}
}只要对目标类型实现了 FromStr trait就可以用 parse 把字符串转换成目标类型。
// 两种提供类型的方式
let parsed: i32 5.parse().unwrap();
let turbo_parsed 10.parse::i32().unwrap();表达式
代码块也是表达式所以它们可以用作赋值中的值。
代码块中实际执行的 最后一个表达式 将作为代码块的返回 注意不要加分号。加了分号就是普通语句最会代码块中就没有执行的表达式因而会返回()
流程控制
if/else
条件不需要用括号包裹
if n 0 {print!({} is negative, n);
} else if n 0 {print!({} is positive, n);
} else {print!({} is zero, n);
}if else 本质上也是代码块因此也可以用于赋值 loop
loop 无限循环
loop {···if 条件 {// 跳过这次迭代的剩下内容continue;}if 条件 {// 退出循环break;}
}循环设置标签 continue、break 可以通过标签 直接影响外层循环
outer: loop {inner: loop {break outer;}
}可以通过break 表达式; 为 loop 设置返回值。
用途尝试一个操作直到成功为止
while
while 条件 {
}for 使用区间标记 a..b 可以创建一个迭代器 a..b 包含b for n in 1..101 {
}for 循环默认会使用 into_iter 函数
for name in names.iter()
for name in names.into_iter()
for name in names.iter_mut()迭代器的方法 into_iter、iter 、iter_mut iter - 在每次迭代中借用集合中的一个元素。这样集合本身不会被改变循环之后仍可以使用。 into_iter - 会消耗集合。在每次迭代中集合中的数据本身会被提供。一旦集合被消耗了之后就无法再使用了因为它已经在循环中被 “移除”move了。 iter_mut - 可变地mutably借用集合中的每个元素从而允许集合被就地修改。 match
match 会检查匹配覆盖
match number {// 匹配单个值1 println!(One!),// 匹配多个值2 | 3 | 5 | 7 | 11 println!(This is a prime),// 试一试 ^ 将 13 添加到质数列表中// 匹配一个闭区间范围13..19 println!(A teen),// 处理其他情况_ println!(Aint special),
}match 解构方式
解构元组
match triple {// 解构出第二个和第三个元素(0, y, z) println!(First is 0, y is {:?}, and z is {:?}, y, z),// .. 可用来忽略元组的其余部分(1, ..) println!(First is 1 and the rest doesnt matter),_ println!(It doesnt matter what they are),
}解构枚举 枚举中的元组也可通过上法解构
解构指针 现在还不懂指针先跳过
match 卫语句guard
可以加上 match 卫语句guard 来过滤分支。 给匹配增加额外的if条件判断
match pair {// “if x y” 是一个卫语句(x, y) if x y println!(These are twins),(x, y) if x y 0 println!(Antimatter, kaboom!),(x, _) if x % 2 1 println!(The first one is odd),_ println!(No correlation...),
}match 重新绑定
在 match 中若间接地访问一个变量则不经过重新绑定就无法在分支中再使用它。 符号 用来绑定变量到名称
match age {n 1 .. 12 println!(Im a child of age {:?}, n),
}if let
判断let是否绑定成功
// 若 let 将 number 解构成 Some(i)则执行
if let Some(i) number {println!(Matched {:?}!, i);
}// 匹配枚举
if let Foo::Bar b {println!(b is foobar);
}直接使用 if Foo::Bara需要注明 #[derive(PartialEq)] while let
与上类似 可以简化 循环与match的组合代码
函数
默认与代码块的返回逻辑相同 但可以 return 提前返回
fn 函数名(参数: 类型, ···) - 返回类型 () {···[return xxx]
}方法
依附于对象的函数
方法在 impl 代码块中定义。 通过关键字 self 来访问对象中的数据和其他。 self 为 self: Self 的语法糖sugar其中 Self 是方法调用者的类型。 self 是 self: Self 的语法糖 mut self 为 self: mut Self self 会消耗本身 self 引用 self mut self 可变引用 self 加入到方法的参数中
impl Point {fn origin() - Point {Point { x: 0.0, y: 0.0 }}fn new(x: f64, y: f64) - Point {Point { x: x, y: y }}
}闭包
声明时使用 || 替代 () 将输入参数括起来。函数体定界符{}对于单个表达式是可选的。有能力捕获外部环境的变量。
|i: i32| - i32 { i 1 };
|i | i 1 ;