`& mut`与函数签名中的类型和ident有什么区别?

时间:2016-02-11 22:23:27

标签: rust

在我正在写作的库中,我正在编写一个可以解读Rust的特性。

pub trait Decodeable {
    fn read_and_decode(&mut types::ReadSeeker) -> Result<Self, ::error::Error>;
}

然后我实现了类型:

impl Decodeable for u32 {
    fn read_and_decode(&mut stream: types::ReadSeeker) -> Result<u32, error::Error> {
        try!(stream.big_edian_read_u32());
    }
}

失败了,错误是:

error: method `read_and_decode` has an incompatible type for trait:
 expected &-ptr,
    found trait types::ReadSeeker

我最终想出如果我将函数签名更改为read_and_decode(stream: &mut types::ReadSeeker),它就可以了。

我想了解&mut stream: types::ReadSeekerstream: &mut types::ReadSeeker之间的区别。这感觉它是生锈的一个基本部分,但我不知道它们之间的区别实际上是不同的。

1 个答案:

答案 0 :(得分:1)

&mut x: T无效,除非T&mut U

fn foo(&mut a: i32) {
    unimplemented!()
}

给出了这个错误:

<anon>:1:8: 1:14 error: mismatched types:
 expected `i32`,
    found `&mut _`
(expected i32,
    found &-ptr) [E0308]
<anon>:1 fn foo(&mut a: i32) {
                ^~~~~~

但是,以下功能有效:

fn foo(&mut a: &mut i32) {
    unimplemented!()
}

&mut x: &mut U的含义是,给定&mut U类型的值,通过取消引用来解析&mut U并将结果分配给x (这仅在U实现Copy时有效,否则您将获得“无法移出借来的内容”错误)。在这种情况下,&mut xpattern。您还可以在let语句和match语句中找到模式,其含义始终相同。

fn foo(a: &mut i32) {
    let &mut b = a;
    match a {
        &mut c => unimplemented!()
    }
}

在实践中,我们很少在函数签名中写出类似&mut a: &mut T的内容。