Rust学习笔记(二)数据类型
Rust 学习笔记(二)数据类型
#ProgrammingLanguage/Rust
可变变量
let mut x : u32 = 5;//mut表示是可变变量, :u32表示变量类型,可以不指定,采用默认值i32。
常量
const MAX_POINTS: u32 = 100_000;
shadowing
let x = 5;
let x = x+1;
let x = x*2;
你可以声明一个与先前变量同名的新变量,并且该新变量会覆盖先前的变量。 虽然x是不可变变量,但是可以通过showing机制,进行重名变量初始化,达到类似可变变量的行为。
标量 (scalar)和复合变量(compound) 标量代表一个单一的值,rust有四个主要的标量类型:整型 浮点型 布尔型 字符型。
tuple : tuple是一种聚合不同类型参数到一个类型的类型。(可以理解为可以每个元素类型不同的特殊数组)
let tup: (i32, f64, u8) = (500, 6.4, 1);
可以通过解构方式将三个元素分开。
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {}", y);
还有一种通过序号进行单独访问的办法,序号从0开始。
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
array: 数组中元素的类型必须是一致的。 这里需要特别注意的是,rust中的数组,长度一旦确定,就不能增长或者减短。
函数内的状态和申明:
let y = 6;//没有返回值,不能作为右值
let x = (let y = 6);//错误
表达式可以是语句的一部分:
let y = {
let x = 3;
x + 1
};
//最后y等于4,注意这个表达式block的最后一行没有分号!!!,如果有分号就是一个单纯的语句而已了。
注意区分 statement 和 expression
{
let x = 3;
x + 1
}//expression
{
let x = 3;
x + 1;
}//statement
函数的返回值可以在函数名的输入参数括号之后通过 - >来进行申明。 函数的返回值,必须是函数体最后的expression。
fn five() -> i32 {
5//没有分号
}
fn main() {
let x = five();
println!("The value of x is: {}", x); }
fn main() {
let x = plus_one(5);
println!("The value of x is: {}", x); }
fn plus_one(x: i32) -> i32 {
x + 1
}
if 表达式: 如果条件为true,则将条件放置在大括号中之后。第一分支为条件表达式为真的分支。
fn main() {
let number = 3;
if number < 5 { //这里和C有明显区别,没有用圆括号括住条件表达式
println!("condition was true");
} else {
println!("condition was false");
} }
比while更为安全的for语句:
let a = [10, 20, 30, 40, 50];
for element in a.iter() {//正向
println!("The value is: {}", element);
}
for number in (1..4).rev() {//反向
println!("{}!", number);
}
⚠️注意一下这种写法是错误的
fn main() {
let a = [10,20,30,40,50];
for element in a.rev() {
println!("The value is {}" , element);
}
}
error[E0599]: no method named `rev` found for array `[{integer}; 5]` in the current scope
--> src/main.rs:3:23
|
3 | for element in a.rev() {
| ^^^ method not found in `[{integer}; 5]`
|
= note: the method `rev` exists but the following trait bounds were not satisfied:
`[{integer}; 5]: std::iter::Iterator`
which is required by `&mut [{integer}; 5]: std::iter::Iterator`
`[{integer}]: std::iter::Iterator`
which is required by `&mut [{integer}]: std::iter::Iterator`
error: aborting due to previous error
简单的介绍了几种数据类型,举一个例子来熟悉新的概念和知识。
- 创建一个新的项目并查看配置文件:
cargo new guessing_game --bin cd guessing_game cat Cargo.toml
[package]
name = "guessing_game" //project or lib name
version = "0.1.0" //verison
authors = ["Your Name <you@example.com>"]
[dependencies] //export libs
- 项目的目的是让使用者输入一个1~100的数字,对比程序随机生成的目标数字,给出大于或者小于的结果,如果没猜中继续输入新的数字,直到猜到为止。 ``` rust use std::io; //引入标准io库
fn main() { println!(“Guess the number!”);
println!("Please input your guess.");
let mut guess = String::new();
io::stdin() //调用标准io库的函数
.read_line(&mut guess) //通过引用将,读到的值传入可修改变量guess
.expect("Failed to read line");//如果读取失败,打印错误信息
println!("You guessed: {}", guess); }
* 引入外部库,产生随机数,修改项目根目录下的Cargo.toml文件
[dependencies] rand = “0.5.5”
然手在命令行执行
``` bash
$ cargo build
Updating crates.io index
Downloaded rand v0.5.5
Downloaded libc v0.2.62
Downloaded rand_core v0.2.2
Downloaded rand_core v0.3.1
Downloaded rand_core v0.4.2
Compiling rand_core v0.4.2
Compiling libc v0.2.62
Compiling rand_core v0.3.1
Compiling rand_core v0.2.2
Compiling rand v0.5.5
Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
Finished dev [unoptimized + debuginfo] target(s) in 2.53s
在项目编译的时候,会自动下载外部carte。(PS:如果在国内使用建议使用镜像),顺道一提,Cargo.lock确保你在编译的时候,会根据你在Cargo.toml文件中指定的外部库的版本,进行编译,但是如果你想更新外部库到最新版本,可以执行 cargo update, 这个命令会忽略Cargo.lock,并下载最新的外部库。
- 完整版本的猜数字代码 ``` rust use rand::Rng; //引入第三方carte use std::cmp::Ordering; //引入标准比较模块 use std::io;
fn main() { println!(“Guess the number!”);
//因为 use rand::Rnd 的引入,可以通过 rand::调用第三方库的公开函数thread_rng()的一个子函数gen_range(),产生一个范围(1~101)之间的随机数
let secret_number = rand::thread_rng().gen_range(1, 101);
//循环读取输入的猜测的数字,并和随机产生的目标数字进行比较
loop {
println!("Please input your guess.");
let mut guess = String::new();
//从标准输入输出,读取到一个字符串形式的数字
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
//将读取到的字符串,通过trim()去掉首尾的空格,再通过parsr()将字符串类型转换为无符号整型参数
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
println!("You guessed: {}", guess);
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break; //猜到正确数字,跳出循环
}
}
} }
⚠️ gen_range在下限包含但在上限不包含,因此我们需要指定1和101以请求1到100之间的数字。
如果你想查询更多cargo相关的说明,执行
``` rust
cargo doc --open
会在浏览器自动弹出帮助页面,会把你项目里面所有用到的库,在左侧列出,点击可以查看细节。