Box<T>

Box<T> 是一个独占资源的智能指针

let b = Box::new(5);
println!("b = {}", b);
// 递归类型
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::{Cons, Nil};
let list = Cons(1,
Box::new(Cons(2,
Box::new(Cons(3,
Box::new(Nil))))));
// Box<T>和引用类型一样支持解引用
// 原因是实现了 Deref 特质
let x = 5;
let y = &x;
let z = Box::new(x);
assert_eq!(5, x);
assert_eq!(5, *y);
assert_eq!(5, *z);

Deref 特质

// 自定义类型实现 Deref 特质
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x: T) -> MyBox<T> {
MyBox(x)
}
}
use std::ops::Deref;
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
let x = 5;
let y = MyBox::new(x);
assert_eq!(5, x);
assert_eq!(5, *y);

强制解引用(Deref coercion)

fn hello(name: &str) {
println!("Hello, {}!", name);
}
let m = MyBox::new(String::from("Rust"));
hello(&m); // hello(&(*m)[..]);

强制解引用的条件:

  • T: Deref<Target=U> 时从 &T&U
  • T: DerefMut<Target=U> 时从 &mut T&mut U
  • T: Deref<Target=U> 时从 &mut T&U

Drop 特质

// 自定义类型实现 Drop 特质
struct CustomSmartPointer {
data: String,
}
impl Drop for CustomSmartPointer {
fn drop(&mut self) {
println!("Dropping CustomSmartPointer with data `{}`!", self.data);
}
}
let c = CustomSmartPointer { data: String::from("my stuff") };
let d = CustomSmartPointer { data: String::from("other stuff") };
println!("CustomSmartPointers created.");
/*
CustomSmartPointers created.
Dropping CustomSmartPointer with data `other stuff`!
Dropping CustomSmartPointer with data `my stuff`!
*/
let c = CustomSmartPointer { data: String::from("some data") };
println!("CustomSmartPointer created.");
drop(c);
println!("CustomSmartPointer dropped before the end of main.");
/*
CustomSmartPointer created.
Dropping CustomSmartPointer with data `some data`!
CustomSmartPointer dropped before the end of main.
*/

Rc<T>

Rc<T> 是一个带引用计数器的智能指针

enum List {
Cons(i32, Rc<List>),
Nil,
}
use self::List::{Cons, Nil};
use std::rc::Rc;
let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
println!("count after creating a = {}", Rc::strong_count(&a)); // strong_count == 1
let b = Cons(3, Rc::clone(&a));
println!("count after creating b = {}", Rc::strong_count(&a)); // strong_count == 2
{
let c = Cons(4, Rc::clone(&a));
println!("count after creating c = {}", Rc::strong_count(&a)); // strong_count == 3
}
println!("count after c goes out of scope = {}", Rc::strong_count(&a)); // strong_count == 2

Cell<T>

Cell<T> 在运行期改变内部的值

let x = Cell::new(1);
let y = &x;
let z = &x;
x.set(2);
y.set(3);
z.set(4);
println!("{}", x.get());
// 相当于以下代码的效果(编译会出错)
let mut x = 1;
let y = &mut x;
let z = &mut x;
x = 2;
*y = 3;
*z = 4;
println!("{}", x);

RefCell<T>

RefCell<T> 在运行期实施借用原则

// 可以有多个不变借用
let a = RefCell::new(15);
let b = a.borrow();
let c = a.borrow();
println!("Value of b is : {}",b);
println!("Value of c is : {}",c);
// 不能同时有不变借用和可变借用
let a = RefCell::new(10);
let b = a.borrow();
let c = a.borrow_mut(); // cause panic.
// 可以有一个可变借用
let a = RefCell::new(15);
let b = a.borrow_mut();
println!("Now, value of b is {}",b);
// 不能有多个可变借用
let a = RefCell::new(15);
let b = a.borrow_mut();
let c = a.borrow_mut(); // cause panic.

链接

Wrapper Types in Rust: Choosing Your Guarantees

Rust Smart Pointers

Rust by Example

Rust Cookbook

Rust语言学习笔记(7)的更多相关文章

  1. Rust语言学习笔记(5)

    Structs(结构体) struct User { username: String, email: String, sign_in_count: u64, active: bool, } let ...

  2. Rust语言学习笔记(6)

    Traits(特质) // 特质 pub trait Summary { fn summarize(&self) -> String; } pub struct NewsArticle ...

  3. Rust语言学习笔记(4)

    Variables and Mutability(变量和可变性) 变量声明有三种:不变量(运行期的常量),变量以及(编译期的)常量. 变量可以重复绑定,后声明的变量覆盖前面声明的同名变量,重复绑定时可 ...

  4. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  5. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  6. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

  7. GO语言学习笔记(一)

    GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...

  8. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  9. Go语言学习笔记十三: Map集合

    Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ...

随机推荐

  1. mysql 8.0 错误The server requested authentication method unknown to the client

    mysql 安装了最新版本8.0.11后创建用户并授权后,授权的用户连接数据库提示 The server requested authentication method unknown to the ...

  2. 虚拟机挂载光盘,同时修改yum源为光盘挂载目录

    VMware下挂载光盘并安装文件https://blog.csdn.net/gfd54gd5f46/article/details/53968293 linux修改yum本地源的方法https://w ...

  3. @postconstruct初始化的操作(转载)

    原文地址:https://www.cnblogs.com/qingruihappy/p/7861623.html 从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注 ...

  4. Noip数学整理

    目录 Noip数学整理 序 1 取模相关 2 质数相关 3.基本操作 4.方程相关 5.数列相关 6.函数相关 Noip数学整理 序 因为某些原因, Noip对于数学方面的考纲仅停留在比较小的一部分, ...

  5. Java 工程名上有个红色叹号

    biuldpath把带×号的jar包remove保存,重新添加jar包

  6. appium java 在android7.0真机上测试程序时报错command failed shell "ps 'uiautomator'"的解决方式

    1.找到appium的安装目录下的adb.js文件,目录为:Appium\node_modules\appium\node_modules\appium-adb\lib 2.打开adb.js,找到如下 ...

  7. 查看Selinux和关闭Selinux

    查看Selinux和关闭Selinux   注:本文非原创文章,转自以下: 链接:https://www.jianshu.com/p/a7900dbf893c 查看SELinux状态: /usr/sb ...

  8. [work]Spring_Jdbc

    封装Spring-RowMapper,使得使用更加灵活 import java.sql.ResultSet; import java.sql.SQLException; import java.uti ...

  9. django之前-----web应用与框架

    一web应用 web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件.应用程序有两种模式C/S.B/S. 下面来看一个简 ...

  10. 20165205 2017-2018-2《Java程序设计》结对编程一 第二周总结

    20165205 2017-2018-2<Java程序设计>结对编程一 第二周总结 设计思路 编写主类Arithmetic4 编写ArithmeticFunc类来实现计算,其中包括:加.减 ...