简体   繁体   中英

How can I return a reference wrapped by `Option` by implementing `Deref` in Rust?

I have a wrapper struct which stores an Option field. I would like to get a reference to the data stored in this field. The following code compiles.

struct Wrapper {
    val: Option<i32>
}

impl Wrapper {
    // lifetime specifier elided because Rust compiler can infer it
    // to be fn my_deref<'a>(&'a self) -> Option<&'a i32>
    fn my_deref(&self) -> Option<&i32> {
        self.val.as_ref()
    }
}

However, I prefer implementing Deref trait for Wrapper , so that I can have dereference coercion which is very nice. I tried the following code but the compiler complains.

use std::ops::Deref;
struct Wrapper {
    val: Option<i32>
}

impl Deref for Wrapper {
    type Target = Option<&i32>; // It tells me I need a lifetime specifier.
    fn deref(&self) -> Option<&i32> {
        self.val.as_ref()
    }
}

I then tried to add a lifetime specifier, but failed again.

use std::ops::Deref;
struct Wrapper<'a> { // It tells me 'a is never used.
    val: Option<i32>
}

impl<'a> Deref for Wrapper<'a> {
    type Target = Option<&'a i32>;
    fn deref(&'a self) -> Option<&'a i32> {
        self.val.as_ref()
    }
}

What is the correct way to implement deref that does the same thing as my_deref ?

After reading turbulencetoo's comment, I come up with the following code, which does exactly what I intend. By program logic the Option field will never be None , so I can safely unwrap it. I must use Option to wrap it for some other reason irrelevant to this topic.

use std::ops::Deref;
struct Wrapper {
    val: Option<i32>
}

impl Deref for Wrapper {
    type Target = i32;
    fn deref(&self) -> &i32 {
        self.val.as_ref().unwrap()
    }
}

Quoting turbulencetoo's comment below.

Implementing Deref for T does not mean that you can get a U from a T! It means that you can get an &U from an &T. In this case, the new Option that is created by the as_ref call in the deref function is not the same Option that your Wrapper stores, and as such you can't return a reference to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM