文章目录
- 1. 目的
- 2. 搞懂 hello world
- 2.1 代码
- 2.2 `fn` 的含义
- 2.3 `main()` 的含义
- 2.4 `println!` 的含义
- 2.5 行尾分号是必要的吗?
- 2.6 左花括号可以放下一行吗?
- 3. 数据类型的例子
- 3.1 代码
- 3.2 rust 的注释
- 3.3 编译运行结果
- 3.4 基本数据类型
- 4. 整数类型的例子
- 4.1 代码
- 4.2 还是代码
- 4.3 整数类型的最大值、最小值
- 5. 浮点类型
- 5.1 不能给浮点类型赋值为整数
- 5.2 浮点类型赋值
- 6. References
1. 目的
通过一些微型的 rust 样例代码, 学习 rust 的基本语法,以及整数、浮点数类型的初步使用。
2. 搞懂 hello world
2.1 代码
使用 cargo new hello-rust 创建的工程中,代码如下:
fn main()
{
println!("Hello, world!");
}
2.2 fn
的含义
rust 的一个关键字。表示函数
2.3 main()
的含义
函数名称, 也是程序入口点。相当于C/C++可执行程序的 main()
函数.
尝试把 main()
改为 main2()
:
fn main2() {
println!("Hello, world!");
}
编译会报错:
zz@Legion-R7000P% cargo run
Compiling hello-rust v0.1.0 (/home/zz/work/rust_abc/hello-rust)
error[E0601]: `main` function not found in crate `hello_rust`
--> src/main.rs:3:2
|
3 | }
| ^ consider adding a `main` function to `src/main.rs`
For more information about this error, try `rustc --explain E0601`.
error: could not compile `hello-rust` (bin "hello-rust") due to previous error
2.4 println!
的含义
println!
是 rust 语言预定义的一个宏。rust 语言中的宏是以 !
结尾。可以暂时把 rust 的宏理解为 “函数的加强版”。
2.5 行尾分号是必要的吗?
乍一看, println!
这句去掉分号也能运行:
fn main() {
println!("Hello, world!")
}
但 rust 中的分号的含义是: 压制表达式的结果。也就是说,如果表达式结尾没有分号, 那么表达式(的返回值)就会被返回。
举一个和是否用;
导致不同结果的例子:
let a = {
let inner = 2;
inner * inner
};
let b = {
let inner = 2;
inner * inner;
};
其中 a 的值将为4, 而 b 的类型并不是整数类型。
zz@Legion-R7000P% cat src/main.rs
fn main() {
println!("Hello, world!");
let a = {
let inner = 2;
inner * inner
};
println!("{}", a);
}
zz@Legion-R7000P% cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/hello-rust`
Hello, world!
4
zz@Legion-R7000P% cat src/main.rs
fn main() {
println!("Hello, world!");
let a = {
let inner = 2;
inner * inner
};
println!("{}", a);
let b = {
let inner = 2;
inner * inner;
};
println!("{}", b);
}
zz@Legion-R7000P% cargo run
Compiling hello-rust v0.1.0 (/home/zz/work/rust_abc/hello-rust)
error[E0277]: `()` doesn't implement `std::fmt::Display`
--> src/main.rs:13:20
|
11 | inner * inner;
| - help: remove this semicolon
12 | };
13 | println!("{}", b);
| ^ `()` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `()`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0277`.
error: could not compile `hello-rust` (bin "hello-rust") due to previous error
2.6 左花括号可以放下一行吗?
fn main()
{
println!("Hello, world!")
}
实际编译运行了下, 可以使用的; 不过 rustfmt 则要求说应该放在同一行1。
为了保持代码结构的良好可读性,Rust 中定义各种语言项,包括控制结构(if / match 等)、函数、结构体、枚举等,要求左花括号与其定义保持同一行。
3. 数据类型的例子
3.1 代码
代码来自2 和 3:
data_type.rs
:
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>());
}
fn main() {
let food = "清蒸螃蟹"; // string 字符串类型
let price = 7767517; // float 类型
let checked = true; // boolean 类型
println!("food is {}", food);
print_type_of(&food);
println!("price is {}", price);
print_type_of(&price);
println!("checked is {}", checked);
print_type_of(&checked);
}
3.2 rust 的注释
Rust 中的注释方式与其它语言(C、Java)一样,支持两种注释方式:
// 这是第一种注释方式
/* 这是第二种注释方式 */
/*
* 多行注释
* 多行注释
* 多行注释
*/
个人比较习惯 //
作为注释符号, 因此在 ~/.vimrc
中的注释快捷键命令里进行配置:
"-- prepend comment chars in each line
" https://vi.stackexchange.com/questions/8128/how-to-toggle-comments-with-ctrl
noremap <C-m> :<S-Left>exe "<S-Right>normal! I".b:commentType<CR>
" autocmd BufReadPost *.[ch] let b:commentType='// '
autocmd FileType c let b:commentType='// '
autocmd FileType cpp let b:commentType='// '
autocmd FileType python let b:commentType='# '
autocmd FileType cmake let b:commentType='# '
autocmd FileType vim let b:commentType='" '
autocmd FileType rust let b:commentType='// '
3.3 编译运行结果
rustc data_type.rs
./data_type
food is 清蒸螃蟹
&str
price is 7767517
i32
checked is true
bool
Rust 是一个静态的严格数据类型的语言。每个值都有唯一的数据类型,要么是整型,要么是浮点型等等。
Rust 语言在赋值时并不强制要求指定变量的数据类型,Rust 编译器可以根据分配给它的值自动推断变量的数据类型。
上面的代码中,我们并没有为每一个变量指定它们的数据类型。Rust 编译器会自动从 等号 = 右边的值中推断出该变量的类型。例如 Rust 会自动将 双引号 阔起来的数据推断为 字符串,把没有小数点的数字自动推断为 整型。把 true 或 false 值推断为 布尔类型。
3.4 基本数据类型
Rust 语言中有四种标量数据类型:
- 整型
- 浮点型
- 布尔类型
- 字符类型
4. 整数类型的例子
let price = 100;
默认类型是 i32.
4.1 代码
int_types.rs
:
fn main() {
let price = 100;
let price2:u32 = 200;
let price3:i32 = -300;
let price4:isize = 400;
let price5:usize = 500;
println!("price is {}", price);
println!("price2 is {} and price3 is {}", price2, price3);
println!("price4 is {} and price5 is {}", price4, price5);
let price6:i32 = 66.66;
let price7:i8 = 192;
}
其中 let price6:i32 = 66.66
在编译时就报错了, 原因是等号左右两侧的数据类型不匹配:
zz@Legion-R7000P% rustc int_types.rs
error[E0308]: mismatched types
--> int_types.rs:12:22
|
12 | let price6:i32 = 66.66;
| --- ^^^^^ expected `i32`, found floating-point number
| |
| expected due to this
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
4.2 还是代码
这次把刚刚报错的 price6 一行注释掉。
fn main() {
let price = 100;
let price2:u32 = 200;
let price3:i32 = -300;
let price4:isize = 400;
let price5:usize = 500;
println!("price is {}", price);
println!("price2 is {} and price3 is {}", price2, price3);
println!("price4 is {} and price5 is {}", price4, price5);
//let price6:i32 = 66.66;
let price7:i8 = 192;
}
编译运行, 发现 price7 这行报错了, 原因是等号右侧的值 192 超过了等号左侧数据范围 [ − 128 , 127 ] [-128, 127] [−128,127]
zz@Legion-R7000P% rustc int_types.rs
warning: unused variable: `price7`
--> int_types.rs:13:9
|
13 | let price7:i8 = 192;
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_price7`
|
= note: `#[warn(unused_variables)]` on by default
error: literal out of range for `i8`
--> int_types.rs:13:21
|
13 | let price7:i8 = 192;
| ^^^
|
= note: the literal `192` does not fit into the type `i8` whose range is `-128..=127`
= help: consider using the type `u8` instead
= note: `#[deny(overflowing_literals)]` on by default
error: aborting due to previous error; 1 warning emitted
4.3 整数类型的最大值、最小值
fn main() {
println!("std::u128::MAX is {}, std::i128::MAX is {}, std::i128::MIN is {}", std::u128::MAX, std::i128::MAX, std::i128::MIN);
println!("std::u64::MAX is {}, std::i64::MAX is {}, std::i64::MIN is {}", std::u64::MAX, std::i64::MAX, std::i64::MIN);
println!("std::u32::MAX is {}, std::i32::MAX is {}, std::i32::MIN is {}", std::u32::MAX, std::i32::MAX, std::i32::MIN);
println!("std::u16::MAX is {}, std::i16::MAX is {}, std::i16::MIN is {}", std::u16::MAX, std::i16::MAX, std::i16::MIN);
println!("std::u8::MAX is {}, std::i8::MAX is {}, std::i8::MIN is {}", std::u8::MAX, std::i8::MAX, std::i8::MIN);
}
zz@Legion-R7000P% ./int_types
std::u128::MAX is 340282366920938463463374607431768211455, std::i128::MAX is 170141183460469231731687303715884105727, std::i128::MIN is -170141183460469231731687303715884105728
std::u64::MAX is 18446744073709551615, std::i64::MAX is 9223372036854775807, std::i64::MIN is -9223372036854775808
std::u32::MAX is 4294967295, std::i32::MAX is 2147483647, std::i32::MIN is -2147483648
std::u16::MAX is 65535, std::i16::MAX is 32767, std::i16::MIN is -32768
std::u8::MAX is 255, std::i8::MAX is 127, std::i8::MIN is -128
5. 浮点类型
5.1 不能给浮点类型赋值为整数
fn main() {
let price8:f64 = 99; // compile error
}
zz@Legion-R7000P% rustc float_types.rs
error[E0308]: mismatched types
--> float_types.rs:2:22
|
2 | let price8:f64 = 99; // compile error
| --- ^^
| | |
| | expected `f64`, found integer
| | help: use a float literal: `99.0`
| expected due to this
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
5.2 浮点类型赋值
默认是 float64 类型。
rust 允许数字的表示中含有下划线,相当于打印版数字中的逗号
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>());
}
fn main() {
//let price8:f64 = 99; // compile error
let price9 = 18.00;
print_type_of(&price9);
let price10:f32 = 8.88;
let price11:f64 = 168.125;
println!("price9 {}", price9);
println!("price10 {}", price10);
println!("price11 {}", price11);
// rust 允许数字的表示中含有下划线,相当于打印版数字中的逗号
let price12 = 1_000_000;
println!("price12 {}", price12);
let price13 = 1_000_000.666_123;
println!("price13 {}", price13);
}
zz@Legion-R7000P% rustc float_types.rs
zz@Legion-R7000P% ./float_types
f64
price9 18
price10 8.88
price11 168.125
price12 1000000
price13 1000000.666123
6. References
P.FMT.04 语言项(Item) 定义时左花括号(brace)位置应该与语言项保持同一行 ↩︎
第 4 章 Rust 的数据类型 ↩︎
如何在Rust中打印一个变量的类型?《跟星哥一起学RUST语言》 ↩︎