I have some value of type A that cannot be cloned, and I have a function f(A) -> B that consumes said value to create a new value B. The A value is created during runtime and is not needed for anything else than creating the B value. But, I have multiple threads that need to see the B value, and the B value needs to be calculated lazily when it is first needed. More precisely, I will be having an Arc<B> that can be cloned to share the B value between threads.
How can I do this?
It seems like a use case for LazyLock or OnceLock, but I could not make it work.
I think I know a solution using RwLock (or Mutex, but I think RwLock would be more efficient) and some contained containing an enum, but I'm wondering if there is an easier solution.
Could you describe your struggles with LazyLock in more detail? Because the closure you pass to LazyLock::new can capture your A instance. You could then share the LazyLock with Arc between your threads. Example.
Be aware of the second generic parameter F on LazyLock. It defaults to fn() -> T, which can't capture. So if you don't let type inference figure out the type for F (i.e. if you were to let ll: LazyLock<B> = ...), then you get the error that function pointers can't capture their environment.