目录所有权与借用所有权引用与借用流程控制模式匹配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());
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!