< 返回版块

Ryu2u 发表于 2022-12-08 09:59

Tags:rust

    let a = Some(Box::new(5));
    let b: Option<&Box<i32>> = a.as_ref();
    let c: &Box<i32> = b.unwrap();
    println!("{}", c);      // 5
    println!("{:?}", b);    // Some(5)
    println!("{:?}", a);    // Some(5)

这里我使用了unwrap来获取Option中的值,按理说我调用完unwrap之后,b应该会被drop,但是这里我依然能够使用它。 unwrap调用的时候不是会获取所有权吗?

评论区

写评论
aj3n 2022-12-08 14:32

反对楼上改成String, 和i32: Copy没有关系; 附议一楼,单纯只是因为Option<&T>: Copy.

JasonkayZK 2022-12-08 11:54

使用 as_ref 只会获得一个不可变引用;

另外,你这里的例子是 i32 类型的,会直接在栈上 Copy 一份新的,应该用 String 测试:

fn main() {
    let a = Some(Box::new(String::from("5")));
    let b: Option<&Box<String>> = a.as_ref();
    let c: &String = b.unwrap();
    println!("{}, type: {}", c, get_type_of(&c));   // 5, type: &alloc::string::String
    println!("{:?}, type: {}", b, get_type_of(&b)); // Some("5"), type: core::option::Option<&alloc::boxed::Box<alloc::string::String>>
    println!("{:?}, type: {}", a, get_type_of(&a)); // Some("5"), type: core::option::Option<alloc::boxed::Box<alloc::string::String>>
}

fn get_type_of<T>(_: &T) -> String {
    std::any::type_name::<T>().to_string()
}

见:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0f5bfd89fcf50dd3481a8c7f7cf783b3

另外,take 方法才会拿出所有权:

fn main() {
    let mut a = Some(Box::new(String::from("5")));
    let b: Option<Box<String>> = a.take();
    let c: Box<String> = b.unwrap();
    println!("{}, type: {}", c, get_type_of(&c));   // 5, type: &alloc::string::String
    println!("{:?}, type: {}", b, get_type_of(&b)); // Compile Error
    println!("{:?}, type: {}", a, get_type_of(&a)); // Compile Error
}

fn get_type_of<T>(_: &T) -> String {
    std::any::type_name::<T>().to_string()
}

报错value被move掉:

error[E0382]: borrow of moved value: `b`
 --> src/main.rs:6:32
  |
3 |     let b: Option<Box<String>> = a.take();
  |         - move occurs because `b` has type `Option<Box<String>>`, which does not implement the `Copy` trait
4 |     let c: Box<String> = b.unwrap();
  |                          - -------- `b` moved due to this method call
  |                          |
  |                          help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
5 |     println!("{}, type: {}", c, get_type_of(&c));   // 5, type: &alloc::string::String
6 |     println!("{:?}, type: {}", b, get_type_of(&b)); // Compile Error
  |                                ^ value borrowed here after move
  |

注意看两个例子里面显式标注的类型;

Grobycn 2022-12-08 10:30

因为 Option<&Box<i32>>: Copy

1 共 3 条评论, 1 页