题外话:关键词ref
与引用符&
在下面一段代码只有一个let
语句里,目的是说明该&ref
操作等价于什么也没有做,它们是相反的操作,类似于操作*
和&
也是相反的操作。
# #![allow(unused_variables)] #fn main() { // File: lib-hello/src/immut/type_ref/mod.rs // Function use_ref_and() let x: u8 = 33; let w: &u8 = &x; let ref y: u8 = x; let z: &u8 = y; println!("x = {:p}", &x); println!("w = {:p}", w); println!("y = {:p}", y); println!("z = {:p}", z); println!("x = {}", x); println!("w = {}", w); println!("y = {}", y); println!("z = {}", z); let &ref y = &x; println!("y = {:p}", y); println!("y = {}", y); println!(); let x: Vec<u8> = vec![33, 42]; let w: &Vec<u8> = &x; let ref y: Vec<u8> = x; let z: &Vec<u8> = y; println!("x = {:p}", &x); println!("w = {:p}", w); println!("y = {:p}", y); println!("z = {:p}", z); println!("x = {:?}", x); println!("w = {:?}", w); println!("y = {:?}", y); println!("z = {:?}", z); let &ref y = &x; println!("y = {:p}", y); println!("y = {:?}", y); #}
借助于工具cargo-clippy,使用下面命令:
# 工具cargo-clippy命令
cargo clippy
可以获取如下编译器的警告信息:
warning: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead
--> lib-hello/src/immut/type_ref/mod.rs:105:9
|
105 | let ref y: u8 = x;
| ----^^^^^--------- help: try: `let y: &u8 = &x;`
|
= note: `#[warn(clippy::toplevel_ref_arg)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#toplevel_ref_arg
从上面警告,可以解读这些内容:
- 在上面程序一段代码包括四个
let
语句里,中间两个是等价的; - 不鼓励在整个
let
语句上使用关键词引用符ref
,而应使用借用符&
; - 从中可以知道,关键词
ref
不应该在let
语句上使用,而更适合在macth
语句里使用它。借用符&
要引用一个对象,而ref
通过引用而不是按值绑定到位置。换句话说,借用符&
实现简单的借用,而引用符ref
则是“借用我,到与我相匹配的位置上去”;
在宏println!()
打印内存地址信息时,只有非引用对象变量,才在变量前面使用借用符&
。要是去掉该引用符&
,编译器将会出现下面错误信息,从中也可以知道,谁是引用谁不是引用对象:
error[E0277]: the trait bound `u8: std::fmt::Pointer` is not satisfied
--> src/main.rs:5:26
|
5 | println!("x = {:p}", x);
| ^ the trait `std::fmt::Pointer` is not implemented for `u8`
|
= note: required by `std::fmt::Pointer::fmt`