往期回顾:
Rust 学习笔记-1 Rust 介绍
Rust 学习笔记-2 Rust 环境安装
Rust学习笔记-2.1 rustup 镜像加速,飞起
Rust 学习笔记-3 Hello World
每种编程语言都有它自己的类型系统, 类型系统用来检查所提供的值的有效性.这样可以确保代码的行为符合预期。
Rust是一种静态类型的语言。Rust中的每个值都是特定的数据类型。编译器可以根据分配给变量的值自动推断变量的数据类型。与c/c++一样. 在使用变量前,需要声明变量类型.
关于类型推断,不同于python,javascript等解释型语言.在运行时推断数据类型. rust 在编译期推断数据类型。
变量声明:
使用let 关键测声明一个变量:
fn main() { let company_string = "您好,Rust World"; // 字符串(string)类型. let rating_float = 4.5; // 浮点型(float) let is_growing_boolean = true; // 布尔型(boolean) let icon_char = '♥'; // unicode 字符类型. println!("company name is:{}",company_string); println!("company rating on 5 is:{}",rating_float); println!("company is growing :{}",is_growing_boolean); println!("company icon is:{}",icon_char);}
运行结果:company name is:您好,Rust Worldcompany rating on 5 is:4.5company is growing :truecompany icon is:♥
标量类型
枚举类型、字符型和各种整数的表示形式统一叫做标量类型。当在表达式中使用标量类型的值时,编译器就会自动将这些标识符转换为整数保存。这种机制的作用是,在这些标量类型上执行的操作与整型上执行的操作完全一样。
标量类型表示单个值。例如,10, 3.14,'a'。Rust 有四种主要的标量类型。
- 整数
- 浮点型
- 布尔值
- 字符
后面的讲讲每种类型
整数型(Integer)
整数是一个没有小数部分的数字。简单地说,整数数据类型用于表示整数。
整数可以进一步分为有符号和无符号。
- 有符号整数可以存储负值和正值。
- 无符号整数只能存储正值。
整数类型如下所示-
长度arch 在这里表示根据具体的cpu架构确定, 32位x86 机器的整数就是32bit. 64位机器的整数就是64bit
例子:
fn main() { let result = 10; // i32 默认. let age:u32 = 20; let sum:i32 = 5-15; let mark:isize = 10; let count:usize = 30; println!("result value is {}",result); println!("sum is {} and age is {}",sum,age); println!("mark is {} and count is {}",mark,count);}
输出结果:
result value is 10sum is -10 and age is 20mark is 10 and count is 30
上面的例子中,如果你讲age 改为一个浮点数. let age:u32=20.5, 编译将失败.
整数范围
每个有符号变量可以存储从-(2^(n-1)到2^(n-1)-1的数字,其中n是变量使用的位数。例如,i8可以存储从-(2^7)到2^7-1的数字,这里我们用8代替了n。
每个无符号变量可以存储从0到(2^n)-1的数字。例如,u8可以存储0到2^7的数字,即0到255。
整数溢出
当分配给整型变量的值超过Rust为数据类型定义的范围时,就会发生整数溢出。让我们用一个例子来理解这一点:
let age: u8 = 255; // u8 区间: 0 到255. let weight: u8 = 256; //溢出 值是 0 let height: u8 = 257; //溢出 值是 1 let score: u8 = 258; //溢出 值是 2 println!("age is {} ", age); println!("weight is {}", weight); println!("height is {}", height); println!("score is {}", score);
编译器默认是不允许这种情况发生的. 输出结果是这样的. 编译失败.
我们如果允许溢出.
#[allow(overflowing_literals)] fn demo4() { let age: u8 = 255; // u8 区间: 0 到255. let weight: u8 = 256; //溢出 值是 0 let height: u8 = 257; //溢出 值是 1 let score: u8 = 258; //溢出 值是 2 println!("age is {} ", age); println!("weight is {}", weight); println!("height is {}", height); println!("score is {}", score);}fn main() { demo4();}
输出是这样的.
Finished dev [unoptimized + debuginfo] target(s) in 0.44s Running `targetdebughello-world.exe`age is 255weight is 0height is 1score is 2
无符号u8变量的有效范围是0到255。在上面的例子中,变量的赋值大于255(Rust中整数变量的上限)。在执行时,上面的代码将返回一个error: literal out of range for `u8` 超出了u8的weight、height和score变量的范围。255之后的溢出值将从0、1、2等开始。
浮点数(Float)
Rust中的Float数据类型可以分为f32和f64。f32类型是单精度浮点,f64具有双精度。默认类型为f64。示例:
fn demo5() { let result = 10.00; // 默认是 f64 let interest: f32 = 8.35; let cost: f64 = 15000.600; //双精度 println!("result value is {}", result); println!("interest is {}", interest); println!("cost is {}", cost);}fn main() { demo5();}
输出结果:
result value is 10interest is 8.35cost is 15000.6
自动类型转换
Rust 不支持自动类型转换, 考虑以下这种情况,将一个整数赋值给浮点类型.
fn demo6() { let interest: f32 = 8; // integer assigned to float variable println!("interest is {}", interest);}fn main() { demo6();}
编译器会报类型错误:
Compiling hello-world v0.1.0 (D:demousthello-world)error[E0308]: mismatched types --> srcmain.rs:72:25 |72 | let interest: f32 = 8; // integer assigned to float variable | --- ^ | | | | | expected `f32`, found integer | | help: use a float literal: `8.0` | expected due to thiserror: aborting due to previous errorFor more information about this error, try `rustc --explain E0308`.error: could not compile `hello-world`.To learn more, run the command again with --verbose.
这是不允许的. 题外话,看这里,rust的一大好处是 编译器的提示非常清晰.
数字分隔符
为了提高大数据的可读性, 我们可以使用分隔符"_" 下划线来分隔数字。50,000可以写成50_000。如下例所示。
fn demo7() { let float_with_separator = 11_000.555_001; println!("float value {}", float_with_separator); let int_with_separator = 50_000; println!("int value {}", int_with_separator);}fn main() { demo7();}
cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.43s Running `targetdebughello-world.exe`float value 11000.555001int value 50000
布尔型(Boolean)
布尔类型只有2个值: true或false。使用bool关键字声明布尔变量.
fn demo8() { let isfun: bool = true; println!("Rust 好玩吗 ? {}", isfun);}fn main() { demo8();}
运行结果:
Finished dev [unoptimized + debuginfo] target(s) in 0.41s Running `targetdebughello-world.exe`Rust 好玩吗 ? true
字符(char)
Rust中的字符数据类型支持数字、字母、Unicode和特殊字符。使用char关键字声明字符数据类型的变量。Rust的char类型表示一个Unicode标量值,这意味着它可以表示的不仅仅是ASCII。Unicode标量值的范围从U+0000到U+D7FF以及U+E000到U+10FFFF(包括U+0000和U+D7FF)。
来个栗子:
fn demo9() { let special_character = '@'; // 默认char let alphabet: char = 'A'; let emoji: char = ''; println!("特殊符号 is {}", special_character); println!("字母 is {}", alphabet); println!("字符表情 is {}", emoji);}fn main() { demo9();}
运行结果:
Finished dev [unoptimized + debuginfo] target(s) in 0.07s Running `targetdebughello-world.exe`特殊符号 is @字母 is A字符表情 is
复合类型
复合类型可以将多个值组合为一个类型。Rust有两种基本的复合类型:元组和数组。
元组
元组是将具有各种类型的多个值组合成一个复合类型的一般方法。元组的长度是固定的:一旦声明,它们的大小就不能增长或缩小。
我们通过在括号内写一个逗号分隔的值列表来创建元组。元组中的每个位置都有一个类型,元组中不同值的类型不必相同。
来个栗子:
fn demo10() { let tup: (i32, f64, u8) = (500, 6.4, 1); let tup2 = (300, 'k', 2.4); println!("The value of tup is: {:?}", tup); println!("The value of tup2 is: {:?}", tup2);}fn main() { demo10();}
运行结果:
Finished dev [unoptimized + debuginfo] target(s) in 0.44s Running `targetdebughello-world.exe`The value of tup is: (500, 6.4, 1)The value of tup2 is: (300, 'k', 2.4)
数组
获取多个值集合的另一种方法是使用数组。与元组不同,数组的每个元素都必须具有相同的类型。Rust中的数组与其他一些语言中的数组不同,因为Rust中的数组具有固定的长度像元组。
在Rust中,进入数组的值以逗号分隔的列表形式写在方括号内:
let a = [1, 2, 3, 4, 5]; let b = [3; 5]; // 长度为5得数组,初始化为3 相当于.let b = [3, 3, 3, 3, 3]; let index = 4; let element = a[index]; println!("索引 {} 的元素是 {}", index, element);
运行结果:
Finished dev [unoptimized + debuginfo] target(s) in 0.42s Running `targetdebughello-world.exe`索引 4 的元素是 5
数组元素使用下标访问. 下标从0开始, 这跟其他语言基本一样.
好了,今天就学习到这里了!
希望大家共同交流学习!