如何进行网站设计规划,深圳摇号申请网站,南充网站建设工作室,上海环球金融中心门票一、Rust 和 ref
1.Rust的ref有什么用
根据Rust官方文档https://doc.rust-lang.org/std/keyword.ref.html Rust ref 主要用在模式匹配match的所有权问题中。 ref在 Rust中#xff0c;也是声明一个指针类型变量#xff0c;进一步说明ref和在其它方面区别#xf…一、Rust 和 ref
1.Rust的ref有什么用
根据Rust官方文档https://doc.rust-lang.org/std/keyword.ref.html Rust ref 主要用在模式匹配match的所有权问题中。 ref在 Rust中也是声明一个指针类型变量进一步说明ref和在其它方面区别我们下一篇再说。
Rust的模式匹配可以发生在函数参数和match中
函数参数
fn foo(x: String) {//String::from(test)的所有权已经移交给了xprintln!({},x);// 代码
}fn main() {let mut sString::from(test);foo(s);println!({},s);//s的所有权已经丢失所以不能使用了此处出错
}特别注意一下函数传参也会交出所有权 2.match
fn main() {let x String::from(test);match x {y println!({}, y),// String::from(test)的所有权移动给了y_ println!(Default case, x {:?}, x),}println!(at the end: x {:?}, x);//x的所有权已经丢失不能再使用。
}
特别注意一下match的模式匹配是会交出所有权的。
除了使用引用借用来避免交出所有权的问题在模式匹配中我们可以使用**或ref**来避免交出所有权match中的ref不再遵循借用规则。那么前面的代码我们可以修改为。
函数参数使用**避免**交出所有权
fn foo(x: mut String) {//println!({},x);// 代码
}fn main() {let mut sString::from(test);foo(mut s);//可变/不可变引用不拥有所有权println!({},s);
}代码运行通过 Finished release [optimized] target(s) in 0.20sRunning target/release/world_hello
test
test2、match使用ref避免交出所有权
fn main() {let x String::from(test);match x {ref y println!({}, y),// 其实在match中不是定义一个变量而是声明一个变量ref是进一步声明y是一个引用但是不能够y因为我们不能够在match中声明y的具体类型。_ println!(Default case, x {:?}, x),}println!(at the end: x {:?}, x);
}代码运行通过 Finished release [optimized] target(s) in 0.20sRunning target/release/world_hello
test
test其实这里你可能会问为什么在match中不使用借用避免所有权移动的问题这是因为match本身机制导致的。 在match中我们没有机会声明变量类型,不能用修饰匹配的变量 当然你非要在**match使用**来避免移交所有权的问题我们可以这样做
fn main() {let x String::from(test);match x {//将引用定义在这里y println!({}, y),//这里不能够写成y println!({}, y),_ println!(Default case, x {:?}, x),}println!(at the end: x {:?}, x);
}代码运行也是成功的 Finished release [optimized] target(s) in 0.22sRunning target/release/world_hello
test
at the end: x test我们再来看一个骚的 // 修复错误尽量少地修改代码
// 不要移除任何代码行
fn main() {let mut v String::from(hello,);let r mut v;match r {mut value value.push_str( world!) }
}前面我们说了 我们不能声明匹配变量也就是value,那么**mut 是肯定不能用**的其实第一版修改我们可以改成 // 修复错误尽量少地修改代码
// 不要移除任何代码行
fn main() {let mut v String::from(hello,);let r mut v;match r {value value.push_str( world!) //这样其实value就是可变引用但是mut v本身的所有权被value拿走了}
}根据代码注释如果我们稍加修改就会发现问题 // 修复错误尽量少地修改代码
// 不要移除任何代码行
fn main() {let mut v String::from(hello,);let r mut v;match r {value value.push_str( world!) }println!({},r);
}运行代码
error[E0382]: borrow of moved value: r-- src/main.rs:11:17|
6 | let r mut v;| - move occurs because r has type mut String, which does not implement the Copy trait
...
9 | value value.push_str( world!) | ----- value moved here
10 | }
11 | println!({},r);| ^ value borrowed here after move这里说了mut v的所有权被value拿走了
那我不想被value拿走我们应该怎么做那么这时候ref的作用就来了我们可以这么修改
// 修复错误尽量少地修改代码
// 不要移除任何代码行
fn main() {let mut v String::from(hello,);let r mut v;match *r {//注意这里是*r因为r本身就是str如果传下去rref r 就变成了双重引用不符合题意ref mut value value.push_str( world!) //此时value就是str类型但是这不是引用类型}println!({},r);
}运行代码 Finished release [optimized] target(s) in 0.34sRunning target/release/world_hello
hello, world!前面我们说了ref不遵循借用的那一套规则所以上面的代码是可以运行成功的。
按照正常思路的话(假设)按道理应该是两个可变引用是违背借用原则的会不会是match{}框住了value的作用域导致其实只有一个可变引用
那我们在看一段代码 // 修复错误尽量少地修改代码
// 不要移除任何代码行
fn main() {let mut v String::from(hello,);let r mut v;match *r {ref mut value {value.push_str( world!) ;println!({},r);}}println!({},r);
}运行一下 Finished release [optimized] target(s) in 0.21sRunning target/release/world_hello
hello, world!
hello, world!哈哈我们已经验证完了 ref不遵循借用的那一套规则在match的模式匹配中ref也可以是不拿所有权的一种引用方法。