目录所有权与借用所有权引用与借用流程控制模式匹配match和iflet解构Option模式适用场景全模式列表方法method所有权与借用所有权(Ownership)所有权机制是Rust中管理内存的核心方式。每个值都有一个所有者,而且任何时候只能有一个
所有权机制是 Rust 中管理内存的核心方式。每个值都有一个所有者,而且任何时候只能有一个所有者。当所有者离开作用域时,该值会被自动清理。
基本所有权规则
所有权转移 当你将一个值赋给另一个变量时,原来的变量将不再拥有该值。
示例代码:
fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // 所有权转移
    println!("{}", s2); // 输出 "hello"
    // println!("{}", s1); // 编译错误:s1 已经不再有效
}借用允许你在不改变所有权的情况下访问值。Rust 有两种类型的借用:不可变借用和可变借用。
不可变借用 不可变借用允许你读取但不能修改值。
fn main() {
    let s = String::from("hello");
    let len = calculate_length(&s); // 不可变借用
    println!("The length of '{}' is {}.", s, len);
}
fn calculate_length(s: &String) -> usize {
    s.len()
}可变借用 可变借用允许你修改值,但同一时间内只能有一个可变借用。
fn main() {
    let mut s = String::from("hello");
    change(&mut s); // 可变借用
    println!("{}", s); // 输出 "hello world"
}
fn change(s: &mut String) {
    s.push_str(" world");
}借用规则 在同一时间内,只能有一个可变借用或者任意数量的不可变借用。 借用必须在有效的作用域内。
生命周期确保引用不会超出其所有者的生命周期。生命周期注解用于明确指明引用的有效范围。
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}
fn main() {
    let string1 = String::from("long string is long");
    let string2 = String::from("xyz");
    let result = longest(string1.as_str(), string2.as_str());
    println!("The longest string is {}", result);
}下面是一个综合示例,展示了所有权和借用在实际应用中的使用。
示例代码:字符串处理
fn main() {
    let mut s = String::from("hello");
    // 不可变借用
    let len = calculate_length(&s);
    println!("Length: {}", len);
    // 可变借用
    change(&mut s);
    println!("After change: {}", s);
    // 使用生命周期注解
    let result = longest_with_lifetime(&s, "world");
    println!("Longest: {}", result);
}
fn calculate_length(s: &String) -> usize {
    s.len()
}
fn change(s: &mut String) {
    s.push_str(" world");
}
fn longest_with_lifetime<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}使用 if 和 else 进行条件判断。
示例代码:
fn main() {
    let number = 5;
    if number % 2 == 0 {
        println!("number is even");
    } else {
        println!("number is odd");
    }
}fn main() {
    let mut count = 0;
    while count < 5 {
        println!("count is {}", count);
        count += 1;
    }
    for i in 0..5 {
        println!("i is {}", i);
    }
}模式匹配是 Rust 中的一个强大特性,它可以让你以一种简洁且安全的方式处理数据结构。
match 语句允许你根据不同的模式执行不同的代码块。
let some_value = 1;
match some_value {
    1 => println!("One"),
    2 => println!("Two"),
    _ => println!("Anything else"),
}Option<T> 是 Rust 中常用的类型,表示可能为空的值。
fn main() {
    let some_option = Some(5);
    let none_option: Option<i32> = None;
    match some_option {
        Some(value) => println!("Some value: {}", value),
        None => println!("No value"),
    }
    match none_option {
        Some(value) => println!("Some value: {}", value),
        None => println!("No value"),
    }
}match 语句可以解构元组。
fn main() {
    let point = (1, 2);
    match point {
        (x, y) => println!("Point: ({}, {})", x, y),
    }
}枚举也可以通过 match 语句进行解构。
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}
fn main() {
    let msg = Message::Write(String::from("hello"));
    match msg {
        Message::Quit => println!("Quit"),
        Message::Move { x, y } => println!("Move to ({}, {})", x, y),
        Message::Write(text) => println!("Write: {}", text),
        Message::ChangeColor(r, g, b) => println!("Change color to ({}, {}, {})", r, g, b),
    }
}if let 语句是一种更简洁的方式来匹配单个模式。
fn main() {
    let some_option = Some(5);
    let none_option: Option<i32> = None;
    if let Some(value) = some_option {
        println!("Some value: {}", value);
    } else {
        println!("No value");
    }
    if let Some(value) = none_option {
        println!("Some value: {}", value);
    } else {
        println!("No value");
    }
}fn main() {
    let point = (1, 2);
    if let (x, y) = point {
        println!("Point: ({}, {})", x, y);
    }
}fn main() {
    let msg = Message::Write(String::from("hello"));
    if let Message::Write(text) = msg {
        println!("Write: {}", text);
    }
}fn main() {
    let some_option = Some(5);
    let none_option: Option<i32> = None;
    match some_option {
        Some(value) => println!("Some value: {}", value),
        None => println!("No value"),
    }
    if let Some(value) = none_option {
        println!("Some value: {}", value);
    } else {
        println!("No value");
    }
}use std::fs::File;
use std::io::{self, Read};
fn read_username_from_file(filename: &str) -> Result<String, io::Error> {
    let mut file = File::open(filename)?;
    let mut username = String::new();
    file.read_to_string(&mut username)?;
    Ok(username)
}
fn main() {
    let filename = "username.txt";
    match read_username_from_file(filename) {
        Ok(username) => println!("Username: {}", username),
        Err(e) => println!("Error reading file: {}", e),
    }
    if let Ok(username) = read_username_from_file(filename) {
        println!("Username: {}", username);
    } else {
        println!("Error reading file");
    }
}enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i2),
}
fn main() {
    let msg = Message::Write(String::from("hello"));
    match msg {
        Message::Quit => println!("Quit"),
        Message::Move { x, y } => println!("Move to ({}, {})", x, y),
        Message::Write(text) => println!("Write: {}", text),
        Message::ChangeColor(r, g, b) => println!("Change color to ({}, {}, {})", r, g, b),
    }
    if let Message::Write(text) = msg {
        println!("Write: {}", text);
    }
}let num = 5;
match num {
    5 => println!("Five"),
    _ => println!("Not five"),
}let num = 5;
match num {
    x if x > 0 => println!("Positive: {}", x),
    _ => println!("Not positive"),
}fn main() {
    let point = (3, 4);
    match point {
        (0, 0) => println!("origin"),
        (0, y) => println!("on the y-axis with y = {}", y),
        (x, 0) => println!("on the x-axis with x = {}", x),
        (x, y) => println!("on neither axis: ({}, {})", x, y),
    }
}enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}
fn main() {
    let m = Message::Write(String::from("hello"));
    match m {
        Message::Quit => println!("quit"),
        Message::Move { x, y } => println!("move to ({}, {})", x, y),
        Message::Write(text) => println!("write: {}", text),
        Message::ChangeColor(r, g, b) => println!("change color to ({}, {}, {})", r, g, b),
    }
}struct Point {
    x: i32,
    y: i32,
}
impl Point {
    fn new(x: i32, y: i32) -> Point {
        Point { x, y }
    }
}
fn main() {
    let p = Point::new(3, 4);
    match p {
        Point { x, y } => println!("point at ({}, {})", x, y),
    }
}方法是与特定类型关联的函数,可以访问该类型的实例。
struct Rectangle {
    width: u32,
    height: u32,
}
impl Rectangle {
    fn new(width: u32, height: u32) -> Rectangle {
        Rectangle { width, height }
    }
    fn area(&self) -> u32 {
        self.width * self.height
    }
    fn perimeter(&self) -> u32 {
        2 * (self.width + self.height)
    }
}
fn main() {
    let rect = Rectangle::new(10, 20);
    println!("area is {}", rect.area());      // 输出 200
    println!("perimeter is {}", rect.perimeter()); // 输出 60
}方法可以有多种不同的参数形式,包括引用、可变引用等。
struct Rectangle {
    width: u32,
    height: u32,
}
impl Rectangle {
    fn new(width: u32, height: u32) -> Rectangle {
        Rectangle { width, height }
    }
    fn set_width(&mut self, new_width: u32) {
        self.width = new_width;
    }
    fn get_width(&self) -> u32 {
        self.width
    }
}
fn main() {
    let mut rect = Rectangle::new(10, 20);
    println!("initial width is {}", rect.get_width()); // 输出 10
    rect.set_width(15);
    println!("new width is {}", rect.get_width());     // 输出 15
}让我们通过一个更复杂的示例来综合运用这些概念。
示例代码:实现一个简单的计算器
enum Operation {
    Add,
    Subtract,
    Multiply,
    Divide,
}
struct Calculator {
    current_value: f64,
}
impl Calculator {
    fn new() -> Calculator {
        Calculator { current_value: 0.0 }
    }
    fn perform_operation(&mut self, operation: Operation, value: f64) {
        match operation {
            Operation::Add => self.current_value += value,
            Operation::Subtract => self.current_value -= value,
            Operation::Multiply => self.current_value *= value,
            Operation::Divide => {
                if value != 0.0 {
                    self.current_value /= value;
                } else {
                    println!("Cannot divide by zero");
                }
            }
        }
    }
    fn get_current_value(&self) -> f64 {
        self.current_value
    }
}
fn main() {
    let mut calculator = Calculator::new();
    calculator.perform_operation(Operation::Add, 5.0);
    calculator.perform_operation(Operation::Multiply, 2.0);
    calculator.perform_operation(Operation::Subtract, 3.0);
    calculator.perform_operation(Operation::Divide, 2.0);
    println!("Current value: {}", calculator.get_current_value());
}枚举 Operation
enum Operation {
    Add,
    Subtract,
    Multiply,
    Divide,
}Operation 定义了四种不同的操作:加法、减法、乘法和除法。结构体 Calculator
struct Calculator {
    current_value: f64,
}Calculator 有一个字段 current_value,用于存储当前计算的结果。new 方法创建一个新的 Calculator 实例,初始值为 0.0。实现 Calculator
impl Calculator {
    fn new() -> Calculator {
        Calculator { current_value: 0.0 }
    }
    fn perform_operation(&mut self, operation: Operation, value: f64) {
        match operation {
            Operation::Add => self.current_value += value,
            Operation::Subtract => self.current_value -= value,
            Operation::Multiply => self.current_value *= value,
            Operation::Divide => {
                if value != 0.0 {
                    self.current_value /= value;
                } else {
                    println!("Cannot divide by zero");
                }
            }
        }
    }
    fn get_current_value(&self) -> f64 {
        self.current_value
    }
}fn main() {
    let mut calculator = Calculator::new();
    calculator.perform_operation(Operation::Add, 5.0);
    calculator.perform_operation(Operation::Multiply, 2.0);
    calculator.perform_operation(Operation::Subtract, 3.0);
    calculator.perform_operation(Operation::Divide, 2.0);
    println!("Current value: {}", calculator.get_current_value());
} 
                如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!