Use `Option<&Db>` instead of `Option<Db>` as a field of a struct?

Hello, I have a struct like

pub struct ConfigManager {
    config: Arc<ConfigManagerConfig>,
    database: Option<sled::Db>,
}

But I want to change the type of Option<sled::Db> to Option<&sled::Db>.

If I change it, I will need to specify a lifetime parameter of ConfigManager.
This would make things a bit more complicated.

Any suggestions?

Any reference has a lifetime, so the complication is inevitable.

In essence, any reference (and any struct containing one) is a temporary borrow of something else, and that's what lifetimes represent. You must prove to the compiler that this "temporary" thing is indeed temporary, and, yes, this is quite complex task in non-trivial cases.

If you want to store sled::Db by pointer (and not inline), you probably want to use Box<sled::Db> (for exclusive access), Arc<sled::Db> (for shared readonly access), or Arc<Mutex<sled::Db>> (for shared mutable access).

2 Likes

My suggestion is to use Option<sled::Db> without the reference.

1 Like

This is the "Welcome to Rust" moment, where you realize what programming with lifetimes actually means: pain. (Pain now rather than later, at least)

If you need to use a value from multiple places, generally you want an Rc or Arc, it means you don't need to worry about lifetimes and it all just works, the ref count and heap cost is generally trivial. If you need to also mutate, generally you want an Rc<RefCell<>> or Arc<Mutex<>>.

You can get more clever with raw refs in structs, but honestly it's generally not worth the brain time. Once you get some experience using other people's lifetime parameters, and feel like your job isn't hard enough anymore, you can start really playing with lifetimes in structures. Generally it's only useful for short term parameters in generic contexts though.

1 Like