所有权可以说是Rust核心概念,这让Rust不需要垃圾回收(garbage collector)就可以保障记忆体安全。Rust的安全性和所有权的概念息息相,因此理解Rust中的所有权如何运作是非常重要的
用下面这段程序描述变数范围的概念
{
// 在宣告以前,变数s无效
let s = "hello";
// 这里是变数s的可用范围
}
// 变数范围已经结束,变数s无效
变数作用域是变数的一个属性,其代表变数的可使用范围,默认从宣告变数开始有效直到变数所在作用域结束。
定义一个变数并赋予值,这个变数的值存在记忆体中,例如需要用户输入的一串字串由於长度的不确定只能存放在堆(heap)上,这需要记忆体分配器在执行时请求记忆体并在不需要时还给分配器
在拥有垃圾回收机制(garbage collector, GC)的语言中,GC会追踪并清除不再使用的记忆体,如果没有GC的话则需要在不使用时显式的呼叫释放记忆体
例如C语言
{
char *s = strdup("hello");
free(s); *// 释放s资源*
}
Rust选择了一个不同的道路,当变数在离开作用域时会自动释放例如下面
{
let s = String::from("hello"); // s 在此开始视为有效
// 使用 s
} // 此作用域结束,释放s变数
当变数离开作用域(大括号结束)时会自动呼叫特殊函示drop来释放记忆体
移动(Move)
变数可以在Rust中以不同的方式与相同的资料进行互动
let x = 100;
let y = x;
这个代码将值100绑定到变数x,然後将x的值复制并赋值给变数y现在栈(stack)中将有两个值100。此情况中的数据是"纯量型别"的资料,不需要存储到堆中,仅在栈(stack)中的资料的"移动"方式是直接复制,这不会花费更长的时间或更多的存储空间。"纯量型别"有这些:
现在来看一下非纯量型别的移动
let s1 = String::from("hello");
let s2 = s1;
String物件的值"hello"为不固定长度长度型别所以被分配到堆(heap)
当s1赋值给s2,String的资料会被拷贝,不过我们拷贝是指标、长度和容量。我们不会拷贝指标指向的资料
前面説当变数超出作用域时,Rust自动调用释放资源函数并清理该变数的记忆体。但是s1和s2都被释放的话堆(heap)区中的"hello"被释放两次,这是不被系统允许的。为了确保安全,在给s2赋值时 s1已经无效了
let s1 = String::from("hello");
let s2 = s1;
println!("{}, world!", s1); // 会发生错误 s1已经失效了
克隆(clone)
正常情况下Rust在较大资料上都会以浅拷贝的方式,当然也有提供深拷贝的method
let s1 = String::from("hello");
let s2 = s1.clone();
println!("{} {}", s1, s2);
输出
hello hello
<<: Day 24:专案06 - 股市趋势图01 | 单月股市API、Pandas
>>: Day 14 : 笔记篇 01 — 了解 Obsidian 的 Metadata,建立一套可持续迭代的笔记系统
今天要和大家介绍的是前端部署网页的方法,分别是以下三个: Vercel AWS S3 Netlif...
-重要性分析和业务影响分析 业务影响分析(BIA)是业务连续性管理的关键过程。它分析了中断对关键活...
27 - Concern 最後整理的方式再来讲到 Rails 提供功能,主要目的在把相同逻辑 cod...
这是我一边学习一边写下的笔记,如果内容有错,恳请在下方留言跟我说,我会非常感谢的!!! 以下我们用主...
玩OpenWrt第一步当然是制作系统,下载系统映像的入口其实很多,但这个路径我觉得最直观与便捷。可以...