/*
1.rust中借用和引用的附带功效都一样,就是都有生命周期。借用使用&关键字,引用使用ref关键字。借用的对象是必须存在的,引用的对象可以虚拟的,后期附上对象。
2.match的模式匹配上只能使用 ref,在函数声明上只能使用&来表示引用类型
3.非要给区分ref和&到底哪个是引用,哪个是借用。我们可以先从词性划分,引用我归类为名词,而借用归类为动词。&A在表达式上 表示借用A,这是一个动作,那结果就是产出一个引用类型。所以let ref B表示声明了一个引用类型,它只能绑定到某次借用动作上。所以ref 更适合叫引用, &叫借用。
我们在不同情况下解释&的意思:
在表达式上,表示的是借用。
在变量绑定上,表示解地址操作与*类似。
在类型声明上,表示引用类型。
在模式匹配上,无效关键字
那么ref的通用解释是:
在表达式上,无效关键字。
在变量绑定上,表示引用类型。
在类型声明上,无效关键字。
在模式匹配上,表示引用类型。
https://www.jianshu.com/p/ac519d8c5ec9
https://www.cnblogs.com/chen8840/p/12699265.html
https://www.jianshu.com/p/7ac48c978624
*/
#![feature(core_intrinsics)]
fn print_type_name_of<T>(_: T) {
println!("{}", unsafe { std::intrinsics::type_name::<T>() })
}
fn test1() {
let ref a1: i32;
//a = 1; expected `&i32`, found integer help: consider borrowing here: `&1`
a1 = &1;
print_type_name_of(a1); //&i32
let ref a2 = 1;
print_type_name_of(a2); //&i32
let ref a3 = &1;
print_type_name_of(a3); //&&i32
let c = 'Q';
// 赋值语句中左边的 `ref` 关键字等价于右边的 `&` 符号。
let ref ref_c1 = c;
let ref_c2 = &c;
println!("ref_c1 equals ref_c2: {}", *ref_c1 == *ref_c2);
//& 与 * 的关系, 那么&用在绑定上是怎么样的?其实&用在绑定上与*用在表达式上是一样的:
let r1 = &1;
print_type_name_of(r1); //&i32
let &r2 = r1;
print_type_name_of(r2); //i32
let r3 = *r1;
print_type_name_of(r3); //i32
}
fn test2() {
fn f1(_s: &String) {
println!("{:p}", _s);
}
fn f2(ref _s: String) {
println!("{:p}", _s);
}
let s = String::from("hello");
let sref1 = &s;
let ref sref2 = s;
println!("{:p}", sref1);
println!("{:p}", sref2);
f1(&s);
f2(s);
}
fn test3() {
let x = &false;
print_type_name_of(x);
let &x = &false;
print_type_name_of(x);
let ref x = false;
print_type_name_of(x);
let ref x = &false;
print_type_name_of(x);
}
fn test4() {
let os = Some(String::from("s"));
match os {
//Some(s) => { 如果这样写下面的打印信息将不可编译 : value borrowed here after partial move
Some(ref s) => {
print_type_name_of(s); //&alloc::string::String
}
_ => (),
};
println!("{:?}", os);
let os = &Some(String::from("s"));
match os {
Some(s) => {
print_type_name_of(s); //&alloc::string::String
}
_ => (),
};
}
fn main() {
test1();
test2();
test3();
test4();
}