Rust 理解绑定和借用

Rust 理解绑定和借用,rust,Rust,我有以下简单的程序 fn main() { let a = 10; let b: i32; let r: &i32; b = a; // move? r = &a; // borrow? println!("{}", a); println!("{}", b); println!("{}", r); println!("{}", &r); println!("{}", *

我有以下简单的程序

fn main() {
    let a = 10;
    let b: i32;
    let r: &i32;

    b = a;      // move?
    r = &a;     // borrow?

    println!("{}", a);
    println!("{}", b);
    println!("{}", r);
    println!("{}", &r);
    println!("{}", *r);
}
输出是

10
10
10
10
10
  • 即使移动值,第一次打印也不会失败。这是因为原始类型还是我遗漏了什么
  • 第二张照片看起来不错
  • 第三个直接打印引用-我们不应该得到内存地址,因为这是一个引用吗
  • 第四个打印是对一个引用的引用,我想它应该打印一个内存地址
  • 第五次打印似乎很合理,因为(我认为)
    *
    是在操作符处反引用引用引用的
  • 看来我还没完全明白

    请详细解释发生了什么事

    相关的:

    关于1:是的,因为它是一个基本变量,更具体地说,是一种实现
    Copy
    特性的类型。所有这些
    Copy
    -类型都使用复制语义而不是移动语义

    关于3
    println自动取消引用它的参数——这是99%的情况下用户想要的


    关于4:同样,自动取消引用参数。。。直到它成为非引用类型。

    关于1:是的,因为它是一个基本变量,更具体地说是一个实现
    复制特性的类型。所有这些
    Copy
    -类型都使用复制语义而不是移动语义

    关于3
    println自动取消引用它的参数——这是99%的情况下用户想要的


    关于4:同样,自动取消引用参数。。。直到它成为非引用类型。

    1,2=>您使用的是
    i32
    ,实际上是这样的
    b=a.clone()


    3,4,5=>您对。我发现,与rust中的参考资料相比,对所有权/借款进行推理更容易
    r=&a
    意味着
    r
    借用
    a
    以便我以后可以访问它的值,其他人将拥有它并负责删除它

    1,2=>您正在使用的
    i32
    ,也就是说,实际上
    b=a.clone()


    3,4,5=>您对。我发现,与rust中的参考资料相比,对所有权/借款进行推理更容易
    r=&a
    意味着
    r
    借用
    a
    以便我以后可以访问它的值,其他人将拥有它并负责删除它

    其他答案大部分是正确的,但有一些小错误

    1。
    i32
    实现,因此当您将其分配给第二个变量绑定时,第一个绑定不需要失效。实现
    Copy
    的任何类型都将具有此属性

    3。您已要求使用
    {}
    对值进行格式化,该值对应于。对实现
    显示的类型的引用具有以下特点:

    impl<'a, T> Display for &'a T where T: Display + ?Sized {
        fn fmt(&self, f: &mut Formatter) -> Result { Display::fmt(&**self, f) }
    }
    
    扩展版本实际上是这样的(稍微清理):

    因此,所有内容都传递给
    println是一个参考。如果引用打印出内存地址,那就没有多大用处了

    除了有用性之外,Rust更关注值语义,而不是引用语义。当值经常移动和更改地址时,该值的位置不太一致或不太有用

    另见


    其他答案基本正确,但也有一些小错误

    1。
    i32
    实现,因此当您将其分配给第二个变量绑定时,第一个绑定不需要失效。实现
    Copy
    的任何类型都将具有此属性

    3。您已要求使用
    {}
    对值进行格式化,该值对应于。对实现
    显示的类型的引用具有以下特点:

    impl<'a, T> Display for &'a T where T: Display + ?Sized {
        fn fmt(&self, f: &mut Formatter) -> Result { Display::fmt(&**self, f) }
    }
    
    扩展版本实际上是这样的(稍微清理):

    因此,所有内容都传递给
    println是一个参考。如果引用打印出内存地址,那就没有多大用处了

    除了有用性之外,Rust更关注值语义,而不是引用语义。当值经常移动和更改地址时,该值的位置不太一致或不太有用

    另见


    请注意,如果需要,您可以使用
    {:p}
    打印指针值。请注意,如果需要,您可以使用
    {:p}
    打印指针值。请您解释为什么在该委托中是
    &**self
    ,为什么不使用
    &*self
    @treecorder实现是
    for&'a T
    ,还有一个
    &self
    参数(就像说
    self:&self
    )。由于
    Self
    &T
    ,因此
    Self
    参数是
    &T
    ,因此需要取消引用两次。也许如果我再写几次self,它就不再像一个真实的单词了……好吧,这是有道理的。你能给我指一些文档,在那里我可以了解更多关于
    self
    self
    之间的区别吗?@treecoder self是一种类型速记,指的是“当前范围内的类型”(例如
    impl T
    ),self只是一个保留变量名,总是指类型
    self
    (或&self等)。你能解释一下为什么它是
    &**self
    ,为什么不
    &*self
    @tree吗。由于
    Self
    &T
    ,因此
    Self
    参数是
    &T
    ,因此需要取消引用两次。也许如果我再写几次self
    let a = 10;
    
    static __STATIC_FMTSTR: &'static [&'static str] = &["", "\n"];
    
    ::std::io::_print(::std::fmt::Arguments::new_v1(__STATIC_FMTSTR, &match (&a,) {
        (__arg0,) => [::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Display::fmt)],
    }));