Lifetime and matches


#1

I have this piece of code. The idea is to set mapping to a default
value if it is current None. The default value is essentially a
no-op, so this seems easier than checking it for None everytime I
use it later in the code.

let mapping = match mapping {
    Some(m) => m,
    None => &PrefixMapping::default()
};

let write = Write::new(writer, ont, mapping);

However, it is giving me this error. So I understand this.

31 |         None => &PrefixMapping::default(),
|                  ^^^^^^^^^^^^^^^^^^^^^^^-
|                  |                      |
|                  |                      temporary value dropped here while still borrowed
|                  temporary value does not live long enough

I thought to hold ownership of the PrefixMapping outside but this
fails also.

let mut default_mapper = None;
let mapping = match mapping {
    Some(m) => m,
    None => {
        default_mapper = Some(PrefixMapping::default());
        &default_mapper.unwrap()
    }
};

again, with the same ownership error which I don’t quite understand,
since I assumed that default_mapper would take ownership.

In the end, I am left with this:

let mut default_mapper = PrefixMapping::default();
let mapping = match mapping {
    Some(m) => m,
    None => {
        &default_mapper
    }
};

which works but seems unsatisfying because I have to instantiate
default_mapper whether I want it or not.

Any other solutions?


#2

I think that what you want is store a reference to the object or a default instance. Indeed, if you store the reference of a default value, you need to move the real instance with the object, but conceptually this is just like owning the instance (obviously, if you don’t want to instantiate a static default value, which IMHO would be a bad solution).

If you like the idea of reference-or-instance, a Cow is what you need.


#3

You can move the initialization of default_mapper to the None branch:

let default_mapper;
let mapping = match mapping {
    Some(m) => m,
    None => {
        defaul_mapper = PrefixMapping::default();
        &default_mapper
    }
};