rustlings:94
background
conversions/as_ref_mut.rs
AsRef and AsMut allow for cheap reference-to-reference conversions.
Read more about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html
and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.
goal
必要目标
快速通过
trace
具体推进
还是要在 GPT 的辅助下掠过:
核心问题是完成函数:
#![allow(unused)] fn main() { fn num_sq<T>(arg: &mut T) { // TODO: Implement the function body. ??? } // 对应的测试 #[test] fn mult_box() { let mut num: Box<u32> = Box::new(3); num_sq(&mut num); assert_eq!(*num, 9); } }
看起来就是对 arg 进行自乘而已
但是照猫画虎才发现:
#![allow(unused)] fn main() { fn num_sq<T>(arg: &mut T) where T: std::ops::Mul<Output = T> + std::ops::MulAssign + Copy { let square = *arg * *arg; *arg *= *arg; *arg = square; } }
这样触发一系列问题:
error[E0277]: cannot multiply `Box<u32>` by `Box<u32>`
--> exercises/conversions/as_ref_mut.rs:86:16
|
86 | num_sq(&mut num);
| ------ ^^^^^^^^ no implementation for `Box<u32> * Box<u32>`
| |
| required by a bound introduced by this call
|
= help: the trait `Mul` is not implemented for `Box<u32>`
note: required by a bound in `num_sq`
--> exercises/conversions/as_ref_mut.rs:47:14
|
46 | fn num_sq<T>(arg: &mut T)
| ------ required by a bound in this
47 | where T: std::ops::Mul<Output = T> + std::ops::MulAssign + Copy
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `num_sq`
error[E0277]: cannot multiply-assign `Box<u32>` by `Box<u32>`
--> exercises/conversions/as_ref_mut.rs:86:16
|
86 | num_sq(&mut num);
| ------ ^^^^^^^^ no implementation for `Box<u32> *= Box<u32>`
| |
| required by a bound introduced by this call
|
= help: the trait `MulAssign` is not implemented for `Box<u32>`
note: required by a bound in `num_sq`
--> exercises/conversions/as_ref_mut.rs:47:42
|
46 | fn num_sq<T>(arg: &mut T)
| ------ required by a bound in this
47 | where T: std::ops::Mul<Output = T> + std::ops::MulAssign + Copy
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `num_sq`
error[E0277]: the trait bound `Box<u32>: Copy` is not satisfied
--> exercises/conversions/as_ref_mut.rs:86:16
|
86 | num_sq(&mut num);
| ------ ^^^^^^^^ the trait `Copy` is not implemented for `Box<u32>`
| |
| required by a bound introduced by this call
|
note: required by a bound in `num_sq`
--> exercises/conversions/as_ref_mut.rs:47:64
|
46 | fn num_sq<T>(arg: &mut T)
| ------ required by a bound in this
47 | where T: std::ops::Mul<Output = T> + std::ops::MulAssign + Copy
| ^^^^ required by this bound in `num_sq`
error: aborting due to 3 previous errors
因为 Box
建议修改后的代码:
#![allow(unused)] fn main() { fn num_sq<T>(arg: &mut T) where T: std::ops::Deref<Target = u32> + std::ops::DerefMut, { let square = **arg * **arg; **arg = square; } }
在这个版本的代码中,T 类型必须实现 std::ops::Deref 和 std::ops::DerefMut trait,这样就可以使用解引用操作符 * 来获取 Box
值得注意的是,在这个版本的代码中,我们不需要显式地实现 Copy trait,因为 u32 类型已经实现了 Copy trait,而 T 类型需要实现 Deref<Target = u32> trait,所以也就具有了 Copy trait 的能力。
而以上提示是换了3种姿势, 才诱使 GPT 给出的, 之前绕的方向更加无解...
所以, 这也只能是一个特殊场景, 如果是自己实现的话, 一定要使用对应合理的内置类型, 不折腾.
refer.
关键参考
logging
版本记要
- ..
- 230330 ZQ init.
_~--^~_
\) / ◴ ◵ \ ()
'_ ▽ _'
| '--#--' )
...act by ferris-actor v0.2.4 (built on 23.0303.201916)