文章目录概述引用的定义引用的规则Deref特型隐式解引用规则.操作符引用的生命周期通过链表探索引用的生命周期使用前后节点指针查找并修改指定节点相关参考概述Rust语言定义了两种引用类型不可变引用也称作共享引用可以读取引用的值但是不能修改。好处是可以同时持有某个值的任意多个共享引用可变引用可以读取和修改引用的值但同一时刻不能拥有对该值的任何其它引用。引用的定义let mut a: i32 5; let a_ref: i32 a; // 创建不可变引用 let a_mref: mut i32 mut a; // 创建可变引用引用的规则Rust引用需要遵循以下基本规则规则1在任意给定时间要么只能有一个可变引用要么只能有多个不可变引用规则2引用必须总是有效的。Deref特型Deref特型用于自定义解引用操作符*的行为。通过实现Deref特型将某类型像引用一样处理trait Deref{ type Target:?Sized; fn deref(self) - Self::Target; } trait DerefMut: Deref{ fn deref_mut(mut self) - mut Self::Target; }隐式解引用规则编译器发现不能够编译通过时会在三种情况下尝试进行隐式解引用所有的三种情况如下T转为U其中T: DerefTargetUmut T转为mut U其中T: DerefMutTargetUmut T转为U其中T: DerefTargetU.操作符在Rust中引用是通过操作符现实创建的而解引用也要显式使用*操作符// 从这里开始都是Rust代码了 let x 10; let r x; // x是对x的共享引用 assert!(*r 10); // 显式地对r解引用由于 Rust 代码中会广泛使用引用因此 . 操作符会在必要时对其左操作数进行隐式解引用struct Anime { name: static str, bechdel_pass: bool }; let aria Anime { name: Aria: The Animation, bechdel_pass: true }; let anime_ref aria; assert_eq!(anime_ref.name, Aria: The Animation);除了隐式解引用. 操作符在方法调用需要时还可以隐式借用对其左操作数的引用。let mut v vec![1973, 1968]; v.sort(); // 隐式借用了对v的可修改引用 (mut v).sort(); // 等价在Rust 中则必须使用 和* 操作符来创建和追随引用只有 . 操作符例外它会隐式地借用和解引用。引用的生命周期Rust会给程序中的每个引用类型附加一个生命周期类似于作用域生命周期的范围与如何使用该引用相匹配。所谓NLL生命周期表示形式就是从借用时间开始到你最后一次使用它结束当然泛型作用域生命周期例外。变量的生命周期必须包含或涵盖该变量引用的生命周期保存在变量中的引用其类型必须保证它在变量的整个生命周期内都有效自初始化始至离开作用域止。通过链表探索引用的生命周期在其它语言中实现链表是一件很简单的事情但是因为所有权机制的存在Rust实现链表可谓困难重重甚至有本书《Too Many Linked Lists》专门来讲解如何在Rust中实现链表。使用前后节点指针我们在实现链表的插入/删除操作时通常会使用到当前节点的前节点指针或者后节点指针。我们参考其它语言的逻辑对应的Rust代码如下let mut cur mut slef.head; let mut prev; while let Some(node) cur { prev cur; cur mut node.next; // node是对cur的再借用在node生命周期内不能使用cur }当然Rust编译器拒绝了这种代码报错如下由于node是对cur的可变再借用在node生命周期内不能使用cur变量因此prev cur;违背了所有权规则。查找并修改指定节点let mut cur mut self.head; while let Some(node) cur { if node.data ! val { cur mut node.next; } } // do something编译报错相关参考《Rust程序语言》《Rust程序语言设计》
探索Rust语言之引用
文章目录概述引用的定义引用的规则Deref特型隐式解引用规则.操作符引用的生命周期通过链表探索引用的生命周期使用前后节点指针查找并修改指定节点相关参考概述Rust语言定义了两种引用类型不可变引用也称作共享引用可以读取引用的值但是不能修改。好处是可以同时持有某个值的任意多个共享引用可变引用可以读取和修改引用的值但同一时刻不能拥有对该值的任何其它引用。引用的定义let mut a: i32 5; let a_ref: i32 a; // 创建不可变引用 let a_mref: mut i32 mut a; // 创建可变引用引用的规则Rust引用需要遵循以下基本规则规则1在任意给定时间要么只能有一个可变引用要么只能有多个不可变引用规则2引用必须总是有效的。Deref特型Deref特型用于自定义解引用操作符*的行为。通过实现Deref特型将某类型像引用一样处理trait Deref{ type Target:?Sized; fn deref(self) - Self::Target; } trait DerefMut: Deref{ fn deref_mut(mut self) - mut Self::Target; }隐式解引用规则编译器发现不能够编译通过时会在三种情况下尝试进行隐式解引用所有的三种情况如下T转为U其中T: DerefTargetUmut T转为mut U其中T: DerefMutTargetUmut T转为U其中T: DerefTargetU.操作符在Rust中引用是通过操作符现实创建的而解引用也要显式使用*操作符// 从这里开始都是Rust代码了 let x 10; let r x; // x是对x的共享引用 assert!(*r 10); // 显式地对r解引用由于 Rust 代码中会广泛使用引用因此 . 操作符会在必要时对其左操作数进行隐式解引用struct Anime { name: static str, bechdel_pass: bool }; let aria Anime { name: Aria: The Animation, bechdel_pass: true }; let anime_ref aria; assert_eq!(anime_ref.name, Aria: The Animation);除了隐式解引用. 操作符在方法调用需要时还可以隐式借用对其左操作数的引用。let mut v vec![1973, 1968]; v.sort(); // 隐式借用了对v的可修改引用 (mut v).sort(); // 等价在Rust 中则必须使用 和* 操作符来创建和追随引用只有 . 操作符例外它会隐式地借用和解引用。引用的生命周期Rust会给程序中的每个引用类型附加一个生命周期类似于作用域生命周期的范围与如何使用该引用相匹配。所谓NLL生命周期表示形式就是从借用时间开始到你最后一次使用它结束当然泛型作用域生命周期例外。变量的生命周期必须包含或涵盖该变量引用的生命周期保存在变量中的引用其类型必须保证它在变量的整个生命周期内都有效自初始化始至离开作用域止。通过链表探索引用的生命周期在其它语言中实现链表是一件很简单的事情但是因为所有权机制的存在Rust实现链表可谓困难重重甚至有本书《Too Many Linked Lists》专门来讲解如何在Rust中实现链表。使用前后节点指针我们在实现链表的插入/删除操作时通常会使用到当前节点的前节点指针或者后节点指针。我们参考其它语言的逻辑对应的Rust代码如下let mut cur mut slef.head; let mut prev; while let Some(node) cur { prev cur; cur mut node.next; // node是对cur的再借用在node生命周期内不能使用cur }当然Rust编译器拒绝了这种代码报错如下由于node是对cur的可变再借用在node生命周期内不能使用cur变量因此prev cur;违背了所有权规则。查找并修改指定节点let mut cur mut self.head; while let Some(node) cur { if node.data ! val { cur mut node.next; } } // do something编译报错相关参考《Rust程序语言》《Rust程序语言设计》