【发布时间】:2022-01-24 09:10:53
【问题描述】:
我对@987654321@ 的理解是,它应该提供一种通用的方式来获取与可变引用“等效*”的参数,即它可以廉价地转换为可变引用。
但是,我遇到了以下示例代码,我试图使用AsMut 只是为了通用slice、arr 和Vec,但它似乎只是在复制我的数组,而不是将可变引用传递给它并就地修改它:
pub fn uses_asmut<T, M>(mut m: M)
where M: AsMut<[T]> {
m.as_mut().swap(0,1);
}
#[test]
pub fn test_swap() {
let arr = [1,2];
uses_asmut(arr);
assert_eq!(arr, [2,1]);
}
(注意,我知道一定有问题,因为我显然将arr 的所有权作为参数传递给uses_asmut,但是当我再次使用arr 时,借用检查器不会在下一行抱怨!如果我将其更改为uses_asmut(&mut arr),则测试通过,但我认为编写的代码甚至不应该编译!)
【问题讨论】:
-
我认为这仅仅是由于数组实现了
Copy,uses_asmut(arr);在按值传递时会复制它。 -
绑定在
uses_asmut()中的AsMut允许您使用arr和&mut arr调用它。如果你用arr调用它,你必须接受数组将被移动(或复制)到函数中。您的let arr = [1, 2]甚至不包括mut的事实表明该数组不会改变。如果您在AsMut背后的想法是调用uses_asmut(arr)并将其脱糖到uses_asumut(&mut arr),我认为这是不可能的,Rust 不会那样工作。您必须将&mut设为显式,或将uses_asmut()实现为宏。 -
在函数参数上放置一个特征绑定会限制你可以传入的类型。它不会改变这些类型的任何内容,或者它们的行为方式。
-
谢谢@MartinGallagher 我想这是我的困惑。我希望 arr 被移动,但它被复制了,因为数组实现了
Copy。