Rust AsMut 复制而不是采用可变引用?
Rust AsMut copying rather than taking mutable reference?
我对 AsMut
的理解是,它应该提供一种通用方法来获取“等效于* 可变引用的参数,即它可以廉价地转换为可变引用。
但是,我遇到了下面的示例代码,我尝试使用 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)
,则测试通过,但我认为编写的代码甚至不应该编译!)
转换应该很便宜。但是你是按值传递数组,而且从来没有人说这很便宜。您可以传递 &mut arr
以不复制数组。
当我们说转换应该很便宜时,我们的意思是“不要做像 str::from_utf8_mut()
这样需要扫描整个字符串的事情”。实际上,从 [T; N]
到 [T]
的转换非常便宜:非常便宜,它由编译器自动发生(强制转换)。
但这并不意味着它等同于可变引用,因为它不是可变引用。它是一个通用类型。如果您想要一个可变引用,请使用一个可变引用。您甚至可以使用 AsMut
,例如 &mut impl AsMut<[T]>
.
没有办法 AsMut
可以阻止您移动(或复制)东西,但也不要求您在调用站点键入 &mut
。
我对 AsMut
的理解是,它应该提供一种通用方法来获取“等效于* 可变引用的参数,即它可以廉价地转换为可变引用。
但是,我遇到了下面的示例代码,我尝试使用 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)
,则测试通过,但我认为编写的代码甚至不应该编译!)
转换应该很便宜。但是你是按值传递数组,而且从来没有人说这很便宜。您可以传递 &mut arr
以不复制数组。
当我们说转换应该很便宜时,我们的意思是“不要做像 str::from_utf8_mut()
这样需要扫描整个字符串的事情”。实际上,从 [T; N]
到 [T]
的转换非常便宜:非常便宜,它由编译器自动发生(强制转换)。
但这并不意味着它等同于可变引用,因为它不是可变引用。它是一个通用类型。如果您想要一个可变引用,请使用一个可变引用。您甚至可以使用 AsMut
,例如 &mut impl AsMut<[T]>
.
没有办法 AsMut
可以阻止您移动(或复制)东西,但也不要求您在调用站点键入 &mut
。