I'm able to express the variance of a LazyCell that's initialized via a capturing closure like so:
use std::cell::LazyCell;
#[derive(Clone, Copy)]
struct ComplexType {
// ...
}
impl ComplexType {
pub fn expensive(self) -> String {
// ...
}
}
impl Default for ComplexType {
fn default() -> Self {
// ...
}
}
fn main() {
let foo = ComplexType::default();
// captures foo with a move, so second type param implements Fn() -> String
let bar: LazyCell<String, _> = LazyCell::new(move || foo.expensive());
// do something with the lazily initialized value
}
I can't figure out the way to express this if I want to encapsulate a bunch of lazily evaluated values though:
use std::cell::LazyCell;
#[derive(Clone, Copy)]
struct ComplexType {
// ...
}
impl ComplexType {
pub fn expensive(self) -> String {
// ...
}
}
impl Default for ComplexType {
fn default() -> Self {
// ...
}
}
struct LazyInit {
field1: LazyCell<ComplexType>,
// ...
}
fn main() {
let foo = ComplexType::default();
// rustc error: closures can't be coerced into fn ptrs if they capture a value
// I'd have to make `LazyInit` generic over every single `LazyCell` instance that it encapsulates
let bar: LazyCell<String, _> = LazyCell::new(move || foo.expensive());
let lazy_values = LazyInit { field1: bar };
// do something with the lazily initialized value
}
Is there any other way to express this sort of lazy field initialization without making the containing type generic over every single LazyCell
field?