pattern-match/patterns #192
Replies: 40 comments 23 replies
-
根据报错信息:
猜测一下6报错的原因:在匹配后,程序试图对 match r {
&mut value => value.push_str(" world!")
} 由于某种原因, 对于解构的猜测可能不太对,可变引用的变量不能被转移的原因也不是很明白,求解惑🥺 |
Beta Was this translation helpful? Give feedback.
-
我的想法如下 fn main() {
let mut v = String::from("hello,");
let r = &mut v;
// 🌟🌟 使用模式 &mut V 去匹配一个可变引用时,你需要格外小心,因为匹配出来的 V 是一个值,而不是可变引用
// 这里被匹配成了一个值,r就相当于String::from("hello,")
// value就相当于这个值的可变引用 &mut String
match r {
value => value.push_str(" world!")
}
} |
Beta Was this translation helpful? Give feedback.
-
我的猜测,不确定是否正确,欢迎大家指出错误: match (&mut v) {
(&mut value) => value.push_str(" world!")
} 然后 |
Beta Was this translation helpful? Give feedback.
-
第6题如果不想交出所有权可以这样写,提供一个思路// 修复错误,尽量少地修改代码
// 不要移除任何代码行
fn main() {
let mut v = String::from("hello,");
let r = &mut v;
match *r {
ref mut value => value.push_str(" world!")
}
} |
Beta Was this translation helpful? Give feedback.
-
#![allow(unused)] let msg = Message::Hello { id: 5 }; match msg { 请问一下为什么第一个分支,只有绑定id才能输出,而第三个却不用 |
Beta Was this translation helpful? Give feedback.
-
😢第六题,引用和解引用让我彻底蒙圈 |
Beta Was this translation helpful? Give feedback.
-
第六题报错的原因其实可以看成是value代表的就是v,所以使用push_str存在问题 &mut value = &mut v 一般的解决方法是如下 fn main() {
let mut v = String::from("hello,");
let r = &mut v;
match r {
value => value.push_str(" world!")
}
} 此时 fn main() {
let mut v = String::from("hello,");
let r = &mut v;
match &mut *r {
value => value.push_str(" world!")
}
println!("{}",r);
} 这里采用了 |
Beta Was this translation helpful? Give feedback.
-
最后一题可以配合这个加深理解: https://stackoverflow.com/questions/62960584/do-mutable-references-have-move-semantics |
Beta Was this translation helpful? Give feedback.
-
Output:
|
Beta Was this translation helpful? Give feedback.
-
.rustc_info.json:
|
Beta Was this translation helpful? Give feedback.
-
在表达式上,表示的是借用。 在表达式上,无效关键字。 |
Beta Was this translation helpful? Give feedback.
-
第6题的个人理解, 如有错误, 欢迎大家指正! 前提: 1. 共享引用实现了"Copy"特型, 2. 可修改引用未实现"Copy"特型, 也就是说可修改引用会发生转移而不是复制. 将第六题的代码修改为: value => value.push_str(" world!"), 在模式匹配成功时, 实际上发生的是: value = r, 而r为可修改引用, 所以此时发生了转移(为了保证只存在一个可修改引用)而不是复制. 所以r失效, 而value成为了唯一的可修改引用, 执行完match中的语句后value生命期结束, 可修改引用失效, 此后String实例的所有者v又恢复了读写权. 另外还有一个比较关于函数的可变引用参数的小知识点: https://stackoverflow.com/questions/62960584/do-mutable-references-have-move-semantics |
Beta Was this translation helpful? Give feedback.
-
fn main() {
} |
Beta Was this translation helpful? Give feedback.
-
rusttttttt |
Beta Was this translation helpful? Give feedback.
-
6题个人理解为 fn main() {
let mut v = String::from("hello,");
let r = &mut v; //对可变字符串v取得可变引用r
// r.push_str(" world!") push_str方法为引用操作方法,因此match后的模式匹配均为可变引用变量
match r {
// 因此此处value为可变引用变量,匹配成功后取得&mut v所有权,即为&mut v.因此无需为&mut value形式
// 作者此处应该是想与Some这种模式匹配做区分因此故意误导,但Some模式为解构模式,此处&引用为类字面量模式,无法解构也无需解构,因此使用value匹配即可
value => value.push_str(" world!")
}
} |
Beta Was this translation helpful? Give feedback.
-
看到这么多人都在第6题上产生疑惑,恳请作者增加一点说明,或者修改一下该题目的难度级别标识:两级难度,对一些人来说却比前几道三级难度的题要难。 一个简单的报错例子:
该练习题中,将 以下代码可以编译通过:
顺便回顾一下
这里通过 用 |
Beta Was this translation helpful? Give feedback.
-
对第六题的个人理解对于6题,其已经涉及到pattern一些底层机制了。在2016年Rust 对match进行了相当大的重构提升: 强烈建议:圣经作者应该在这里加一些基本说明,我一个小白没日没夜查了三天资料和做各种测试又在StackOverflow上和人讨论也只能懂个大概。PS:和人聊过就发现Rust剧烈的版本变动以及为了方便而引入各种隐式玄学语法糖其实很招人骂,这和Rust鼓励工程师理解和思考全流程细节的哲学相违背。我们正在讨论的这个RFC 就是其中之一。而且Rust作者对 具体来说Rust将 以下是RFC
非引用模式除开以下模式都是
而下面的例子,x的值`String`在heap上不支持
然后借助vscode具体看下第六题的答案:
结合vscode推断的类型我这么理解match的过程:
如果我的推断是正确的,那么
输出结果: 但是我还有个疑惑需要解答。在获得
所以我检查了
输出结果:
可以看到地址完全相同,所以Rust使用的是开销最低的借用,这也不会影响 引用模式以上我们完成了正确答案工作过程的分析。接下来我们看一下包含错误的题面。
简单定义引用模式:当输入变量有 体面中显式使用 还是先看VScode的推断,
这和非引用模式在隐式添加 既然输入的
编译就会报出和第六题一模一样的错误,祸根就是这个解引用!我还没有细致研究解引用的机制(看了一些,太复杂了,怕是得研究许多天ORZ)但是可以做一些推断。 解引用会需要调用
输出:
可以看到被借用对象 而要修复故障,就需要删除 小节RFC( |
Beta Was this translation helpful? Give feedback.
-
第六题法二: fn main() {
let mut v = String::from("hello,");
let r = & v;
match r {
value => v.push_str(" world!")
}
} |
Beta Was this translation helpful? Give feedback.
-
第六题是否可以理解成编译器会对 match 值是引用作解引用,所以 match 里面只能够匹配值而不是引用? |
Beta Was this translation helpful? Give feedback.
-
mark finished |
Beta Was this translation helpful? Give feedback.
-
为什么第四题不能是:
|
Beta Was this translation helpful? Give feedback.
-
Done , good one there , |
Beta Was this translation helpful? Give feedback.
-
Done ✅ |
Beta Was this translation helpful? Give feedback.
-
pattern-match/patterns
Learning Rust By Practice, narrowing the gap between beginner and skilled-dev with challenging examples, exercises and projects.
https://zh.practice.rs/pattern-match/patterns.html
Beta Was this translation helpful? Give feedback.
All reactions