在Option <Rc <Struct >>上调用映射的方式与在Option <Rc <i32 >>上调用映射的方式不同

时间:2019-06-22 16:44:22

标签: rust smart-pointers dereference reference-counting

我是Rust的新手,我想弄清楚为什么Rc在传递给闭包时表现不同。我的完整代码如下:

use std::rc::Rc;

struct Something {
    value: i32
}

fn main() {
    let wrapped_struct = Some(Rc::new(Something { value: 1 }));
    let wrapped_integer = Some(Rc::new(1));
    // Case 1: This works
    let works: Option<i32> = wrapped_struct.map(|i| { i.value });
    // Case 2: This fails
    let fails: Option<i32> = wrapped_integer.map(|i| { i });
}

错误消息是:

   |
13 |     let fails: Option<i32> = wrapped_integer.map(|i| { i });
   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found struct `std::rc::Rc`
   |
   = note: expected type `std::option::Option<i32>`
              found type `std::option::Option<std::rc::Rc<{integer}>>`

我不明白的是为什么在第一个闭包(案例1)中我可以将i用作Something(我希望Rc<Something>)却在第二个闭包中(案例2)我不能将i用作i32(实际上得到了Rc<i32>)。

我感谢所有指向相关文档的指针。非常感谢!

1 个答案:

答案 0 :(得分:2)

两个闭包中i的类型实际上分别是Rc<Something>Rc<i32>Rc可以取消引用以访问其内部数据,但是为了方便起见,Rust中有一些地方会自动进行取消引用。

在结构情况下,当您编写i.value时,它将自动取消引用i以访问该字段。然后,它返回i32的副本,因为i32Copy类型。因此,表达式i.value的类型为i32。就像您写了(*i).value一样,但是Rust为您做了取消引用。

i32情况下,您只是返回i,其类型仍为Rc<i32>。您可以通过显式取消引用来解决此问题:

wrapped_integer.map(|i| { *i });

另请参阅: