这是我的代码,它可以编译

trait AppendBar {
    fn append_bar(self) -> Self;
}

impl AppendBar for Vec<String> {
    fn append_bar(mut self) -> Self {
        self.push("Bar".to_string());
        self
    }

虽然它取得了所有权,但为什么它能在其实施中变异self ?

推荐答案

因为参数的可变性不是函数签名的一部分.

这个..

fn foo(self) { ... }

...从外表上看和...完全一样.

fn foo(mut self) { ... }

...因为一旦控制转移到函数,参数会发生什么就不是调用者的事了.

因此,特征的实现是允许的,因为从调用者的Angular 来看,签名实际上是相同的.


换句话说,这两个功能有什么不同?

fn foo(mut v: String) {
    // ...
}

fn foo(v: String) {
    let mut v = v; // Rebind v as mutable.
    // ...
}

答案是没有.该函数的值为String,因此它始终可以对其进行变异.如果它能帮助您理解正在发生的事情,您可以认为第一个示例是第二个示例的"捷径",但它们最终的含义是相同的.


注意:这并不是Rust所特有的;在C++中,函数参数的const-ness也不是函数签名的一部分.

Rust相关问答推荐

空字符串转换为Box字符串时是否分配?<>

当为a Self:IntoIterator设置trait bind `时,获取`a T `不是迭代器"&'"<'>&'

为什么对不可复制数据的引用的取消引用没有O权限来避免Rust中的双重释放?

如何找到一个数字在二维数组中的位置(S)?

MacOS(AARCH64)上Ghidra中的二进制补丁导致进程终止

使用 struct 外部的属性来改变 struct 的原始方式

如果成员都实现特征,是否在多态集合上实现部分重叠的特征?

为什么实例方法可以像Rust中的静态方法一样被调用?

在Rust中,如果Result是Err,运行副作用(如日志(log)记录)的惯用方法是什么

当T不执行Copy时,如何返回Arc Mutex T后面的值?

将PathBuf转换为字符串

如果死 struct 实现了/派生了一些特征,为什么Rust会停止检测它们?

为什么 `Deref` 没有在 `Cell` 上实现?

为什么切片时需要参考?

缺失serde的字段无法设置为默认值

如何将 C++ 程序链接到 Rust 程序,然后将该 Rust 程序链接回 C++ 程序? (cpp -> rust -> cpp)

decltype、dyn、impl traits,重构时如何声明函数的返回类型

我如何取消转义,在 Rust 中多次转义的字符串?

为什么 no_std crate 可以依赖于使用 std 的 crate?

在空表达式语句中移动的值