【Rust】——函数(所有权)以及借用或引用

简介: 【Rust】——函数(所有权)以及借用或引用

🎯函数与所有权

       将值传递给函数与给变量赋值的原理相似。向函数传递值可能会移动或者复制,就像赋值语句一样。

fn main() {
    let s = String::from("hello");  // s 进入作用域
 
    takes_ownership(s);             // s 的值移动到函数里 ...
                                    // ... 所以到这里不再有效
 
    let x = 5;                      // x 进入作用域
 
    makes_copy(x);                  // x 应该移动函数里,
                                    // 但 i32 是 Copy 的,
                                    // 所以在后面可继续使用 x
 
} // 这里,x 先移出了作用域,然后是 s。但因为 s 的值已被移走,
  // 没有特殊之处
 
fn takes_ownership(some_string: String) { // some_string 进入作用域
    println!("{}", some_string);
} // 这里,some_string 移出作用域并调用 `drop` 方法。
  // 占用的内存被释放
 
fn makes_copy(some_integer: i32) { // some_integer 进入作用域
    println!("{}", some_integer);
} // 这里,some_integer 移出作用域。没有特殊之处


🎯返回值与所有权

fn main() {
    let s1 = gives_ownership();         // gives_ownership 将返回值
                                        // 转移给 s1
 
    let s2 = String::from("hello");     // s2 进入作用域
 
    let s3 = takes_and_gives_back(s2);  // s2 被移动到
                                        // takes_and_gives_back 中,
                                        // 它也将返回值移给 s3
} // 这里,s3 移出作用域并被丢弃。s2 也移出作用域,但已被移走,
  // 所以什么也不会发生。s1 离开作用域并被丢弃
 
fn gives_ownership() -> String {             // gives_ownership 会将
                                             // 返回值移动给
                                             // 调用它的函数
 
    let some_string = String::from("yours"); // some_string 进入作用域。
 
    some_string                              // 返回 some_string 
                                             // 并移出给调用的函数
                                             // 
}
 
// takes_and_gives_back 将传入字符串并返回该值
fn takes_and_gives_back(a_string: String) -> String { // a_string 进入作用域
                                                      // 
 
    a_string  // 返回 a_string 并移出给调用的函数
}

       变量的所有权总是遵循相同的模式:

  • 将值赋给另一个变量时移动它。
  • 当持有堆中数据值的变量离开作用域时,其值将通过 drop 被清理掉,除非数据被移动为另一个变量所有。


🎯借用与引用

fn main() {
    let s1 = String::from("hello");
 
    let len = calculate_length(&s1);
 
    println!("The length of '{}' is {}.", s1, len);
}
 
fn calculate_length(s: &String) -> usize {
    s.len()
}

       注意变量声明和函数返回值中的所有元组代码都消失了。其次,注意我们传递 &s1 给 calculate_length,同时在函数定义中,我们获取 &String 而不是 String。这些 & 符号就是 引用,它们允许你使用值但不获取其所有权。


       补充:注意:与使用 & 引用相反的操作是 解引用(dereferencing),它使用解引用运算符,*。


       我们将创建一个引用的行为称为 借用(borrowing)。


       正如变量默认是不可变的,引用也一样。(默认)不允许修改引用的值。

可变引用:

fn main() {
    let mut s = String::from("hello");
 
    change(&mut s);
}
 
fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

       提醒:如果你有一个对该变量的可变引用,你就不能再创建对该变量的引用。

       数据竞争data race)类似于竞态条件,它可由这三个行为造成:

  • 两个或更多指针同时访问同一数据。
  • 至少有一个指针被用来写入数据。
  • 没有同步数据访问的机制。


       我们也不能在拥有不可变引用的同时拥有可变引用:

       不可变引用的用户可不希望在他们的眼皮底下值就被意外的改变了!然而,多个不可变引用是可以的,因为没有哪个只能读取数据的人有能力影响其他人读取到的数据。


悬垂引用:

       在具有指针的语言中,很容易通过释放内存时保留指向它的指针而错误地生成一个 悬垂指针(dangling pointer)。

       在 Rust 中编译器确保引用永远也不会变成悬垂状态:当你拥有一些数据的引用,编译器确保数据不会在其引用之前离开作用域。

相关文章
|
3月前
|
存储 Rust 安全
30天拿下Rust之所有权
在编程语言的世界中,Rust凭借其独特的所有权机制脱颖而出,为开发者提供了一种新颖而强大的工具来防止内存错误。这一特性不仅确保了代码的安全性,还极大地提升了程序的性能。在Rust中,所有权是一种编译时检查机制,用于追踪哪些内存或资源何时可以被释放。每当一个变量被赋予一个值(比如:字符串、数组或文件句柄)时,Rust会确定这个变量是否“拥有”这个值,拥有资源的变量负责在适当的时候释放这些资源。
39 5
|
3月前
|
存储 Rust 编译器
30天拿下Rust之函数详解
在Rust中,函数是程序的基本构建块,是代码复用的基本单位,用于封装一系列执行特定操作和计算的语句。函数是可重用的代码片段,可以接受输入参数并产生输出。通过合理使用函数,可以提高代码的可读性、可维护性和可重用性。
45 4
|
4月前
|
存储 Rust 安全
【Rust学习】04_所有权
所有权是 Rust 最独特的特性,对语言的其余部分有着深远的影响。它使 Rust 能够在不需要垃圾收集器的情况下保证内存安全,因此了解所有权的运作方式非常重要。在本章中,我们将讨论所有权以及几个相关功能:借用、切片以及 Rust 如何在内存中布局数据。
27 1
|
4月前
|
Rust 编译器 测试技术
Rust与C++的区别及使用问题之Rust中函数参数传递的问题如何解决
Rust与C++的区别及使用问题之Rust中函数参数传递的问题如何解决
|
4月前
|
Rust
rust 引用了Trait的实现,为什么还需要引入Trait 才能调用实现的方法
rust 引用了Trait的实现,为什么还需要引入Trait 才能调用实现的方法
|
5月前
|
Rust 安全 开发者
Rust引用、借用和所有权详解
Rust引用、借用和所有权详解
|
5月前
|
Rust 开发者
Rust函数入门与函数重载
Rust函数入门与函数重载
120 0
|
6月前
|
Rust 编译器 容器
|
6月前
|
Rust 算法 安全
【Rust中的所有权系统深入解析】A Deep Dive into Rust‘s Ownership System
【Rust中的所有权系统深入解析】A Deep Dive into Rust‘s Ownership System
99 0
|
10天前
|
Rust 安全 Java
探索Rust语言的并发编程模型
探索Rust语言的并发编程模型