代码之家  ›  专栏  ›  技术社区  ›  dpr

为什么不可变特性的实现可以是可变的?

  •  0
  • dpr  · 技术社区  · 3 年前

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

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

    虽然它拥有所有权,但为什么它会在实现中自我变异?

    1 回复  |  直到 3 年前
        1
  •  6
  •   cdhowie    3 年前

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

    这

    fn foo(self) { ... }
    

    …从外面看和…一模一样。。。

    fn foo(mut self) { ... }
    

    …因为一旦控制权转移到函数,参数会发生什么,这与调用方无关。

    因此,特性的实现是允许的,因为从调用者的角度来看,签名实际上是相同的。


    换句话说,这两个函数之间的区别是什么?

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

    答案是没有。这个 String 值被赋予了函数,所以它总是可以使它发生变化。如果它有助于你理解发生了什么,你可以认为第一个例子是第二个例子的“捷径”,但它们最终的意义是一样的。


    请注意,这并不是Rust独有的东西;在C++中, const -函数参数的ness也不是函数签名的一部分。

    推荐文章