matklad / once_cell

Rust library for single assignment cells and lazy statics without macros
Apache License 2.0
1.87k stars 109 forks source link

Implement `Clone` for `Lazy` #202

Closed nsunderland1 closed 1 year ago

nsunderland1 commented 2 years ago

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.

nsunderland1 commented 2 years ago

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

nsunderland1 commented 2 years ago

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

matklad commented 2 years ago

Yeah, I think we should do this for unsync. For sync, it's tricky. We managed to do this for OnceCell: https://github.com/matklad/once_cell/issues/31, but I am not entirelysure that'll work for lazy

nagisakuya commented 1 year ago

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.

matklad commented 1 year ago

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

Which is better:

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.