Rust 语言中60条重要的默认规则总结,代码中的示例涵盖了 Rust 语言的核心特性,包括变量可变性、所有权、类型系统、模块系统、错误处理等多个方面,有助于全面理解 Rust 的默认行为和设计哲学。
分享
在总结中添加rust的内存安全规则
用markdown格式总结rust的错误处理规则
写一段在rust中使用默认规则的代码
rust
//! Rust 语言默认规则总结(共60条)
//! 本文件以注释形式整理了Rust语言的核心默认行为和规则
//! 涵盖语法、类型系统、内存管理等关键方面
fn main() {
// 以下代码仅用于演示各条规则,实际运行可能需要调整
// 1. 变量默认不可变
let x = 5;
// x = 6; // 错误:不能修改不可变变量
let mut y = 5;
y = 6; // 正确:mut变量可修改
// 2. 所有权规则:赋值即转移
let s1 = String::from("hello");
let s2 = s1; // s1所有权转移给s2
// println!("{}", s1); // 错误:s1已失效
// 3. 基本类型默认实现Copy
let x_copy = 5;
let y_copy = x_copy; // 复制x的值
println!("x = {}, y = {}", x_copy, y_copy); // 正确:x仍可用
// 4. 函数参数默认获取所有权
let s_ownership = String::from("test");
take_ownership(s_ownership);
// println!("{}", s_ownership); // 错误:所有权已转移
// 5. 引用默认不可变
let ref_x = 5;
let r = &ref_x;
// *r = 6; // 错误:不可变引用不能修改值
let mut ref_y = 5;
let r_mut = &mut ref_y;
*r_mut = 6; // 正确:可变引用可修改
// 6. 可变引用排他性
let mut exclusive_x = 5;
let r1 = &mut exclusive_x;
// let r2 = &mut exclusive_x; // 错误:已有可变引用
// 7. 语句默认返回单元值()
let a = { 5 + 3 }; // 表达式:a = 8
let b = { 5 + 3; }; // 语句:b = ()
// 8. 结构体字段默认私有
let person = Person {
name: "Alice".to_string(),
age: 30
};
// println!("{}", person.name); // 错误:私有字段不可访问
println!("{}", person.age); // 正确:公共字段可访问
// 9. 模块默认私有
my_module::public_func();
// my_module::private_func(); // 错误:私有函数不可访问
// 10. if条件必须是布尔值
let if_x = 5;
// if if_x { // 错误:x是i32而非bool
// println!("true");
// }
if if_x > 0 { // 正确:条件是bool类型
println!("x为正数");
}
// 11. match必须穷尽所有可能
let dir = Direction::Up;
match dir {
Direction::Up => println!("上"),
Direction::Down => println!("下"),
Direction::Left => println!("左"), // 不可省略
Direction::Right => println!("右"), // 不可省略
}
// 12. 未使用变量默认警告
let unused = 5; // 警告:未使用的变量
let _used = 6; // 无警告:_表示有意忽略
// 13. 整数溢出默认触发panic(调试模式)
// 调试模式下运行会panic
// let overflow_x: u8 = 255;
// let overflow_y = overflow_x + 1; // 溢出
// 14. 函数默认返回()
let result = no_return(); // result是()
// 15. 泛型默认不自动推导
print_generic(5); // 正确:推导T = i32
print_generic::<i32>(5); // 显式指定类型
// 16. 数组长度是类型的一部分
let arr1: [i32; 3] = [1, 2, 3];
let arr2: [i32; 4] = [1, 2, 3, 4];
// let arr3: [i32; 3] = arr2; // 错误:长度不同,类型不匹配
// 17. 字符串默认是UTF-8编码
// 错误:包含无效UTF-8字节
// let invalid_str = String::from_utf8(vec![0xff]).unwrap();
let valid_str = String::from("valid utf-8"); // 正确
// 18. Drop特质默认自动调用
{
let drop_obj = MyType; // 创建变量
} // 离开作用域时自动调用drop
// 19. 切片默认不拥有数据
let slice_str = String::from("hello");
let slice = &slice_str[0..2]; // 切片引用部分数据
// slice_str.clear(); // 错误:不能修改被引用的数据
// 20. 枚举变体默认私有
let _ = PublicEnum::PubVariant;
// let _ = PublicEnum::PrivVariant; // 错误:私有变体不可访问
// 21. 特质方法默认不能直接调用
let trait_obj = MyStruct;
trait_obj.method(); // 正确:通过实例调用
MyTrait::method(&trait_obj); // 正确:完全限定语法
// 22. 静态变量默认必须初始化
// static UNINIT: i32; // 错误:未初始化
// 23. 整数类型默认i32
let int_default = 5; // 默认为i32类型
let int_u32: u32 = 5; // 显式指定为u32
// 24. 浮点数默认f64
let float_default = 3.14; // 默认为f64类型
let float_f32: f32 = 3.14; // 显式指定为f32
// 25. return关键字可省略
let sum = add(2, 3);
assert_eq!(sum, 5);
// 26. 范围默认左闭右开
let range = 1..4; // 包含1, 2, 3
for i in range {
println!("{}", i); // 输出1, 2, 3
}
// 27. 结构体更新语法默认移动所有权
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: 3, ..p1 }; // y从p1移动
// println!("{}", p1.y); // 错误:p1.y所有权已转移
// 28. Box<T>默认在堆上分配
let on_stack = 5;
let on_heap = Box::new(5); // 5存储在堆上
// 29. Result必须显式处理
// 错误:未处理Result
// std::fs::File::open("file.txt");
// 正确:处理Result
match std::fs::File::open("file.txt") {
Ok(_) => println!("文件打开成功"),
Err(e) => println!("文件打开失败: {}", e),
}
// 30. 生命周期默认自动推导
let s1_longest = "long string is long";
let s2_longest = "short";
let result_longest = longest(s1_longest, s2_longest);
println!("最长字符串: {}", result_longest);
// 31. 函数参数按值传递
let by_value_str = String::from("hello");
take_value(by_value_str); // 所有权转移
// 32. 闭包默认捕获环境变量的方式最优
let closure_x = 5;
let closure = || println!("{}", closure_x); // 自动选择不可变借用
closure();
// 33. 元组结构体字段默认按索引访问
let tuple_struct = PointTuple(10, 20);
println!("x: {}", tuple_struct.0); // 通过索引访问
println!("y: {}", tuple_struct.1);
// 34. 单元结构体默认无状态
let unit_struct = Empty; // 单元结构体
unit_struct.do_nothing();
// 35. 泛型trait默认不能作为返回类型
let shape = create_dyn_shape();
println!("面积: {}", shape.area());
// 36. for循环默认迭代迭代器
let iter_vec = vec![1, 2, 3];
for i in iter_vec { // 迭代元素(转移所有权)
println!("{}", i);
}
// 37. 切片模式匹配默认按引用绑定
let slice_match = [1, 2, 3];
match slice_match {
[first, second, ..] => println!("前两个元素: {}, {}", first, second),
_ => (),
}
// 38. mut关键字默认只影响直接绑定
let mut mut_struct = Point { x: 1, y: 2 };
mut_struct.x = 3; // 正确:mut_struct是mut的
// 39. 整数除法默认向下取整
assert_eq!(7 / 3, 2);
assert_eq!(-7 / 3, -3); // 不是-2,向下取整
// 40. 逻辑运算符默认短路求值
let short_x = 5;
let short_y = 0;
if short_x > 0 && short_y / short_x > 0 { // 右侧不执行
// ...
}
// 41. use声明默认导入到当前作用域
use a::f; // 仅在当前作用域可用
f(); // 正确
// 42. as转换默认不检查溢出
let as_x: i32 = 1000;
let as_y = as_x as u8; // 1000超出u8范围,结果为232(无警告)
// 43. 关联函数默认通过::调用
let关联函数 = Person::new("Alice".to_string()); // 通过::调用
// 44. const变量默认编译期计算
const MAX: i32 = 100;
const HALF: i32 = MAX / 2; // 编译期计算
// 45. 数组初始化默认支持重复语法
let array_repeat = [0; 5]; // [0, 0, 0, 0, 0]
let ones: [i32; 3] = [1; 3]; // [1, 1, 1]
// 46. None默认对应Option<T>的空值
let none_opt: Option<i32> = None; // 显式类型
let some_opt = Some(5); // 推导为Option<i32>
// 47. break默认退出当前循环
'outer: for i in 0..5 {
for j in 0..5 {
if i + j > 5 {
break 'outer; // 需显式标签才能退出外层循环
}
}
}
// 48. 字符串字面量默认是&'static str
let static_str: &'static str = "hello"; // 字符串字面量默认是'static
// 49. impl Trait默认只能用于单一类型
let impl_trait1 = returns_impl_trait(true);
let impl_trait2 = returns_impl_trait(false);
println!("impl trait: {}, {}", impl_trait1, impl_trait2);
// 50. 模块路径默认从当前模块开始
c::g();
// 51. #[derive]默认只派生指定trait
let derive_struct = MyStructDerive;
println!("{:?}", derive_struct); // 正确:已派生Debug
// let cloned = derive_struct.clone(); // 错误:未派生Clone
// 52. 裸指针默认不安全
let raw_x = 5;
let ptr = &raw_x as *const i32;
unsafe {
println!("{}", *ptr); // 必须在unsafe块中解引用
}
// 53. 运算符重载默认不自动实现
let op1 = PointOp(1, 2);
let op2 = PointOp(3, 4);
let op_result = op1 + op2; // 已实现Add trait
println!("运算符重载结果: ({}, {})", op_result.0, op_result.1);
// 54. default trait方法默认可被覆盖
let default_impl = MyStructDefault;
default_impl.method(); // 调用覆盖后的实现
// 55. static mut默认不安全
unsafe {
COUNT += 1; // 必须在unsafe块中操作
println!("COUNT: {}", COUNT);
}
// 56. 范围迭代默认产生值而非引用
let iter_ref_vec = vec![1, 2, 3];
for i in iter_ref_vec.iter() { // 迭代引用(&i32)
println!("{}", i);
}
// 57. Self默认指代实现类型
let self_type = MyTypeSelf::new(); // Self等价于MyTypeSelf
// 58. 多行字符串默认保留换行
let multi_line = r#"第一行
第二行
缩进行"#; // 保留所有换行和缩进
println!("多行字符串:\n{}", multi_line);
// 59. Drop顺序默认与声明顺序相反
let drop1 = PrintOnDrop("a");
let drop2 = PrintOnDrop("b");
// 退出作用域时先drop b,再drop a
// 60. cargo默认编译debug模式
// 注:此规则通过cargo命令行为体现,而非代码
println!("程序执行完毕");
}
// 辅助函数和类型定义(用于演示上述规则)
// 4. 函数参数默认获取所有权
fn take_ownership(s: String) {
println!("{}", s);
}
// 8. 结构体字段默认私有
struct Person {
name: String, // 私有字段
pub age: u32 // 公共字段
}
impl Person {
// 43. 关联函数默认通过::调用
fn new(name: String) -> Self {
Person { name, age: 0 }
}
}
// 9. 模块默认私有
mod my_module {
pub fn public_func() { println!("公共函数"); }
fn private_func() { println!("私有函数"); }
}
// 11. match必须穷尽所有可能
enum Direction { Up, Down, Left, Right }
// 14. 函数默认返回()
fn no_return() {
println!("无返回值");
}
// 15. 泛型默认不自动推导
fn print_generic<T>(x: T) where T: std::fmt::Display {
println!("{}", x);
}
// 18. Drop特质默认自动调用
struct MyType;
impl Drop for MyType {
fn drop(&mut self) {
println!("MyType被销毁");
}
}
// 20. 枚举变体默认私有
pub enum PublicEnum {
PubVariant, // 公共变体
#[allow(dead_code)]
PrivVariant // 私有变体
}
// 21. 特质方法默认不能直接调用
trait MyTrait {
fn method(&self) { println!("默认实现"); }
}
struct MyStruct;
impl MyTrait for MyStruct {}
// 22. 静态变量默认必须初始化
static GLOBAL: i32 = 10;
// 25. return关键字可省略
fn add(a: i32, b: i32) -> i32 {
a + b // 自动返回,无需return
}
// 27. 结构体更新语法默认移动所有权
struct Point { x: i32, y: i32 }
// 30. 生命周期默认自动推导
fn longest(s1: &str, s2: &str) -> &str {
if s1.len() > s2.len() { s1 } else { s2 }
}
// 31. 函数参数按值传递
fn take_value(mut s: String) {
s.push_str(" world");
println!("{}", s);
}
// 33. 元组结构体字段默认按索引访问
struct PointTuple(i32, i32);
// 34. 单元结构体默认无状态
struct Empty;
impl Empty {
fn do_nothing(&self) {}
}
// 35. 泛型trait默认不能作为返回类型
trait Shape { fn area(&self) -> f64; }
struct Circle(f64);
impl Shape for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * self.0 * self.0
}
}
fn create_dyn_shape() -> Box<dyn Shape> {
Box::new(Circle(5.0))
}
// 41. use声明默认导入到当前作用域
mod a {
pub fn f() { println!("a::f被调用"); }
}
// 50. 模块路径默认从当前模块开始
mod c {
use super::a::f; // super表示父模块
pub fn g() { f(); }
}
// 51. #[derive]默认只派生指定trait
#[derive(Debug)] // 仅派生Debug
struct MyStructDerive;
// 53. 运算符重载默认不自动实现
use std::ops::Add;
struct PointOp(i32, i32);
impl Add for PointOp {
type Output = Self;
fn add(self, other: Self) -> Self::Output {
PointOp(self.0 + other.0, self.1 + other.1)
}
}
// 54. default trait方法默认可被覆盖
trait MyTraitDefault {
fn method(&self) { println!("默认实现"); }
}
struct MyStructDefault;
impl MyTraitDefault for MyStructDefault {
fn method(&self) { println!("覆盖实现"); }
}
// 55. static mut默认不安全
static mut COUNT: i32 = 0;
// 57. Self默认指代实现类型
struct MyTypeSelf;
impl MyTypeSelf {
fn new() -> Self { // Self等价于MyTypeSelf
MyTypeSelf
}
}
// 59. Drop顺序默认与声明顺序相反
struct PrintOnDrop(&'static str);
impl Drop for PrintOnDrop {
fn drop(&mut self) {
println!("Dropping: {}", self.0);
}
}
// 49. impl Trait默认只能用于单一类型
fn returns_impl_trait(flag: bool) -> impl std::fmt::Display {
if flag {
5 // i32
} else {
10 // 仍返回i32
}
}