Closed REASY closed 1 year ago
Lazy
is initialized on acess, so ZOOM
would also be Lazy<u32>
and CONST_ZOOM
is just not possible.
There is actually an alternative to using Lazy
here, if you are willing to change Settings
to:
use std::borrow::Cow;
#[derive(Debug, Clone)]
pub struct Settings {
pub environment: Cow<'_, str>,
pub path: Cow<'_, str>,
pub zoom: u32
}
impl Settings {
pub const fn new() -> Settings {
Settings { environment: Cow::Borrowed("dev"), path: Cow::Borrowed("foo"), zoom: 1u32 }
}
}
pub const SETTINGS: Settings = Settings::new();
static ZOOM: u32 = SETTINGS.zoom;
const CONST_ZOOM: u32 = SETTINGS.zoom;
Or you can replace String
with CompactString
, which has a const
constructor CompactString::new_inline
for strings that are no longer than 24 bytes on 64-bit platform and strings that are no longer than 12 bytes on 32-bit platform.
Hi, @NobodyXu, thank you the answer!
I cannot go with const SETTINGS
because of my use-case, I'm loading settings from config file using config crate, so cannot be const, right?
error[E0015]: cannot perform deref coercion on `once_cell::sync::Lazy<Settings<'_>>` in statics
--> src/main.rs:85:56
error[E0015]: cannot perform deref coercion on `Cow<'_, str>` in statics
--> src/main.rs:85:55
error[E0015]: cannot call non-const fn `get_gdal_vsi_path` in statics
--> src/main.rs:85:37
Compiler is quite straightforward in the last message, "cannot call non-const fn
get_gdal_vsi_pathin statics
. So there is no way to achieve what I want, having static variable initialized only once instead of creating it in the method always?
Thanks.
I cannot go with const SETTINGS because of my use-case, I'm loading settings from config file using config crate, so cannot be const, right?
In that case, yes, you would have to use OnceCell
or arc-swap
.
In your example:
// Does not compile. I want this to be initialized only once instead of local variable in main
static GDAL_VSI_BASE_PATH: Lazy<String> = Lazy::new(|| get_gdal_vsi_path(&SETTINGS.tile_store.base_path));
Also, OnceCell::get_or_try_init
allow you to call fallible function and return error instead of having to panic.
Thank you, @NobodyXu !
I assume the runtime overhead of the type being lazy is negligible, the case of OnceCell lazy there is nothing heavy in force
method?
Thank you, @NobodyXu !
You are welcome
I assume the runtime overhead of the type being lazy is negligible, the case of OnceCell lazy there is nothing heavy in
force
method?
No, it's just the same as OnceCell.
It's generally quite cheap.
Hello,
I'm trying to get the following code to compile, but didn't succeed.
The errors:
Playground at [rustexplorer](https://www.rustexplorer.com/b#%2F*%0A%5Bdependencies%5D%0Aonce_cell%20%3D%20%221.18.0%22%0A%0A*%2F%0A%0Ause%20once_cell%3A%3Async%3A%3ALazy%3B%0A%0A%23%5Bderive(Debug%2C%20Clone)%5D%0Apub%20struct%20Settings%20%7B%0A%20%20%20%20pub%20environment%3A%20String%2C%0A%20%20%20%20pub%20path%3A%20String%2C%0A%20%20%20%20pub%20zoom%3A%20u32%0A%7D%0A%0A%0Aimpl%20Settings%20%7B%0A%20%20%20%20pub%20fn%20new()%20-%3E%20Settings%20%7B%0A%20%20%20%20%20%20%20%20Settings%20%7B%20environment%3A%20%22dev%22.to_string()%2C%20path%3A%20%22foo%22.to_string()%2C%20zoom%3A%201u32%20%7D%0A%20%20%20%20%7D%0A%7D%0A%0Apub%20static%20SETTINGS%3A%20Lazy%3CSettings%3E%20%3D%20Lazy%3A%3Anew(%7C%7C%20%7B%0A%20%20%20%20Settings%3A%3Anew()%0A%7D)%3B%0A%0A%0Astatic%20ZOOM%3A%20u32%20%3D%20SETTINGS.zoom%3B%0A%0Aconst%20CONST_ZOOM%3A%20u32%20%3D%20SETTINGS.zoom%3B%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22%7B%3A%3F%7D%22%2C%20SETTINGS)%3B%0A%7D)
Thank you.