
^^《榴芒客服系统》是我们工作室开发的在线客服系统欢迎下载试用https://blog.csdn.net/look4liming/article/details/164755808https://blog.csdn.net/look4liming/article/details/164755808在Rust中所有权这个概念内置于语言本身并通过编译期检查强制执行。每个值都有决定其生命周期的唯一拥有者当拥有者被释放时它拥有的值也会同时被释放。在Rust中释放被称为丢弃drop。BoxT是指向存储在堆上的T类型值的指针。因为Box拥有它所指向的空间所以当丢弃Box是也会释放此空间{let point Box::new((0.5, 1.5)); // 在此分配了pointlet label format!({:?}, point); // 在此分配了labelassert_eq(label, (0.5, 1.5)); // 在此全部丢弃了}拥有者及其拥有的那些值形成了一棵树值的拥有者是值的父节点值拥有的值是值的子节点。每棵树的总根都是一个变量当该变量超出作用域时整棵树都将消失。Rust的单一拥有者规则将禁止任何可能让它们排列得比树结构更复杂的可能性。所以Rust确实不如其它语言强大其它所有实用的编程语言都能构建出任意复杂的对象图。Rc和Arc允许值在某些限制下有多个拥有者。在Rust中对大多数类型来说为变量赋值、将其传给函数或从函数返回这样的操作都不会复制值而是会移动值。源会把值的所有权转移给目标并变回未初始化状态改由目标变量来控制值的生命周期。调用向量的clone方法该方法会执行向量及其元素的深拷贝。将参数传给函数会将所有权转移给函数的参数、从函数返回一个值会将所有权转移给调用者、构建元组会将值转移给元组。移动的永远是值本身而不是这些值拥有的堆存储。对于向量和字符串值本身就是指单独的“三字标头”。移动与控制流示例1let x vec![10, 20, 30];if c {f(x); // 移动x} else {g(x); // 移动x}h(x); // 错误只要任何一条路径移动了x的所有权x在这里就是未初始化的示例2let x vec![10, 20, 30];while f() {g(x); // 错误x已经在第一次迭代中被移动给函数g了}示例3let mut x vec![10, 20, 30];while f() {g(x);x h(); // x被赋予了新值因此该循环可以正确执行}let mut v vec![10, 20, 30];let x v[2]; // 错误不能移动到Vec索引结构之外将向量直接传给循环例如for ... in v时会将向量从v中移动出去让v变成未初始化转态。标准Copy类型包括所有整型、浮点型、char类型和boolean类型。Copy类型的元组或固定大小的数组本身也是Copy类型。String不是Copy类型因为它拥有从堆中分配的缓冲区。BoxT也不是Copy类型因为它拥有从堆中分配的引用目标。File类型不是Copy类型因为复制它需要向操作系统申请另一个文件句柄。任何在丢弃值时需要做一些特殊操作的类型都不能是Copy类型Vec需要释放自身元素、File需要关闭自身文件句柄、MutexGuard需要解锁自身互斥锁。默认情况下struct和enum都不是Copy类型。如果此结构体的所有字段本身都是copy类型可以通过将属性#[derive(Copy, Clone)]放置在此定义之上来创建Copy类型#[derive(Copy, Clone)]struct Label {number: u32}试图在一个其字段不全是Copy类型的结构体上这样做会触发编译错误。RcT值是指向附带引用计数的在堆上分配的T型指针。克隆RcT值并不会复制T只会创建另一个指向它的指针并递增引用计数。let s: RcString Rc::new(abc.to_string());Let t: RcString s.clone();所有权规则适用于Rc指针本身当丢弃最后一个现有Rc时Rust也会丢弃T。s.push_str(def); // 错误因为Rc指针拥有的值是不可变的。Rust的内存和线程安全保证的基石是确保不会有任何值时既共享又可变的。Rust制定Rc指针的引用目标通常都可以共享因此就不能是可变的。如果有两个引用计数的值是先相互指向的那么其中一个值就会让另一个值的引用计数保持在0以上因此这些值将永远不被释放。^^《榴芒客服系统》是我们工作室开发的在线客服系统欢迎下载试用https://blog.csdn.net/look4liming/article/details/164755808https://blog.csdn.net/look4liming/article/details/164755808