Why I need Copy trait here?

I've created a structure:

struct ThreadCommands {
    control_tx: [Option<Sender<ControlCommand>>;8],
    draw_rx: [Option<Receiver<DrawCommand>>;8]
}

When I try to initialize it:

    let mut control = ThreadCommands {
        control_tx: [None;8],
        draw_rx: [None;8]
    };

I get an error:

the trait boundstd::option::Option<std::sync::mpsc::Sender>: std::marker::Copy is not satisfied

Can someone explain me, why Copy is needed here? And if I can't provide a Copy, how can I initialize this structure?

(Or, may be, I miss something obvious here).

Update: This works:

ThreadCommands {
            control_tx: [None,None,None,None, None,None,None,None],
            draw_rx: [None,None,None,None, None,None,None,None]
        }

But it looks like a mockery. Are compiler that stupid?

This error message stems from the fact that array initialization of the form [expr; N] requires the type of expr to implement Copy.

See also this website.

In your case, you can just use e.g. control_tx: Default::default().

Another option that has come up in a recent thread (that I’m currently not finding for some reason) is to define some const NO_SENDER: Option<Sender<ControlCommand>> = None; and use [NO_SENDER; 8]. I’m personally feeling like: if constants work, they ought to, eventually, get around to make None work directly as well. Edit2: Nevermind it’s already implemented, just not stabilized. On nightly with #![feature(const_in_array_repeat_expressions)], using None directly works.

Edit - this thread:

3 Likes

Thank you! My case was solved by #[derive(Default)] for struct and Default:default() call.

And thank you for clarification on nightly. My high expectations from Rust was met.

Default::default() is what you want here, as others have said. But for the more general question:

As const generics has been getting better and better, we're also starting to get methods on arrays instead of slices. So for example now there's [T; N]::map on nightly, so this could be done with something silly like [(); 8].map(|()| None) -- and there are PRs for more-helpful methods open.

In the mean time there are crates that do this with macros, such as