matklad / once_cell

Rust library for single assignment cells and lazy statics without macros

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implement `Clone` for `Lazy`

nsunderland1 opened this issue · comments

It seems like it should be possible for Lazy<T, F> (both sync and unsync, unless there's a subtlety that I'm missing) to implement Clone if both T and F implement Clone, keeping in mind that closures implement Clone if all their captures do.

impl<T, F> Clone for Lazy<T, F>
where
    T: Clone,
    F: Clone,
{
    fn clone(&self) -> Self {
        Self {
            // I think it's really this easy? `OnceCell` and `Cell` both implement `Clone` if their contents do
            cell: self.cell.clone(),
            init: self.init.clone(),
        }
    }
}

Right now if you want to clone a Lazy, you're forced to use OnceCell instead.

An amendment: Cell only implements Clone for T: Copy, which makes this less useful but not completely useless.

https://doc.rust-lang.org/std/cell/struct.Cell.html#impl-Clone-for-Cell%3CT%3E

Oh and the implementation I posted above will definitely not work for sync::Lazy, only unsync::Lazy, because of the cell. I think the only way you could implement Clone for sync::Lazy would be to do something silly like force it in clone

Yeah, I think we should do this for unsync. For sync, it's tricky. We managed to do this for OnceCell: #31, but I am not entirelysure that'll work for lazy

Display and Debug and Selialize and etc... also should implemented for Lazy.

const MESSAGE: Lazy<String> = Lazy::new(|| "Hello, World!");
println!("hoge {}",MESSAGE);

This code does not work because Lazy does not implement Display.

Thinking more about this, no, I don't think either sync or unsync flavor should implement Clone.

Which is better:

  • forcing the value and calling T: Clone
  • cloning F and potentially forcing it twice

Seems unclear, and, given that reducing work is the reason for OnceCell to exist, this seems like an important question which is better left to the user to decide.