【Rust】所有权OwnerShip

什么是所有权

rust使用由编译器检查的一些规则构成的所有权系统来管理内存。且这不会影响程序的运行效率。

所有权规则

  • rust中每一个每一个值都有一个owner。
  • 在同一时刻,只能有一个owner。
  • 当这个owner超过范围,则该值会被丢弃。

String类型

为什么需要String

  • 已经有了字符串字面量了,为啥还需要String类型呢?字面量是硬编码在程序里面的,如果我们在编码的时候并不知道字符串是什么,那我们就不能用字符串字面量了。比如字符串来自用户输入,这时候就需要用String类型来存储了。
  • 更多字符串基本用法参考【Rust】字符串String类型学习

内存及分配

简单的情况

在String::from的地方,会申请内存;在}之前rust会调用drop方法释放s的内存。

rust 复制代码
{
    let s = String::from("hello"); // s is valid from this point forward
    // do stuff with s
}                                  // this scope is now over, and s is no
                                   // longer valid

字符串赋值的情况

  • 当将s1赋值给s2的时候,s1就会被废弃,字符串的堆内存就交给s2去管理了。如果赋值后,再使用s1就会出现编译错误。
  • rust语言不会自动进行任何的拷贝,所以可以认为自动拷贝都是高性能的。
  • let s2 = s1这个过程中相当于发生了move的动作,将字符串的所有权从s1移交给s2。
rust 复制代码
    let s1 = String::from("hello");
    let s2 = s1;

字符串克隆的情况

  • 既然直接赋值,会导致所有权转移。那么如何做到赋值时进行拷贝呢?这就需要用到clone方法。
rust 复制代码
let s1 = String::from("hello");
let s2 = s1.clone();
println!("s1 = {s1}, s2 = {s2}");
  • 因为clone方法会拷贝堆上的内存,所以其执行的代价是比较高的。

只在栈上的数据:拷贝

rust 复制代码
let x = 5;
let y = x;
println!("x = {x}, y = {y}");
  • 我们发现如果直接把整数类型x赋值给y,并且在使用x。编译并没有报错。
  • 这是因为整形是固定大小的类型,存放在栈上。拷贝的代价很低,其深拷贝和浅拷贝并没有特别大的区别。所以我们可以直接拷贝,而不需要move。

所有权和函数

  • 按照我们所有权的规则,如下代码就很容易理解。
rust 复制代码
fn main() {
    let s = String::from("hello");  // s comes into scope

    takes_ownership(s);             // s's value moves into the function...
                                    // ... and so is no longer valid here

    let x = 5;                      // x comes into scope

    makes_copy(x);                  // x would move into the function,
                                    // but i32 is Copy, so it's okay to still
                                    // use x afterward

} // Here, x goes out of scope, then s. But because s's value was moved, nothing
  // special happens.

fn takes_ownership(some_string: String) { // some_string comes into scope
    println!("{some_string}");
} // Here, some_string goes out of scope and `drop` is called. The backing
  // memory is freed.

fn makes_copy(some_integer: i32) { // some_integer comes into scope
    println!("{some_integer}");
} // Here, some_integer goes out of scope. Nothing special happens.

返回值和有效范围

rust 复制代码
fn main() {
    let s1 = gives_ownership();         // gives_ownership moves its return
                                        // value into s1

    let s2 = String::from("hello");     // s2 comes into scope

    let s3 = takes_and_gives_back(s2);  // s2 is moved into
                                        // takes_and_gives_back, which also
                                        // moves its return value into s3
} // Here, s3 goes out of scope and is dropped. s2 was moved, so nothing
  // happens. s1 goes out of scope and is dropped.

fn gives_ownership() -> String {             // gives_ownership will move its
                                             // return value into the function
                                             // that calls it

    let some_string = String::from("yours"); // some_string comes into scope

    some_string                              // some_string is returned and
                                             // moves out to the calling
                                             // function
}

// This function takes a String and returns one
fn takes_and_gives_back(a_string: String) -> String { // a_string comes into
                                                      // scope

    a_string  // a_string is returned and moves out to the calling function
}
相关推荐
Bs_MoneyMagnet6 分钟前
基于springboot+vue的滑雪场票务与装备租赁系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·毕业设计·计算机毕业设计
AlienZHOU4 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
狗头大军之江苏分军7 小时前
《潮水漫过十七岁》开学了
后端
苏三说技术7 小时前
如何看待GPT-6在UP主众测中碾压夺冠?它是现在最强大模型吗?
后端
mldong7 小时前
一份 JSON,一条能跑的审批流:把报销流程送上工作流引擎
后端·架构
wno7047 小时前
Spring Boot WebFlux增删改查
java·spring boot·后端
Captaincc7 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
君顾18 小时前
上海24小时自助健身房系统开发实战指南:从架构设计到落地部署
java·开发语言·健身房
香菜TTT8 小时前
大模型上下文协议(MCP):AI 应用的“USB-C”接口技术
开发语言·人工智能·经验分享
aramae8 小时前
模拟实现strlen()函数 (C语言)
c语言·开发语言·后端