How to define array of AtomicBool?

I tried to define an array of core::sync::atomic::AtomicBool with predefined values as

static ELEMENT_EXISTS: [AtomicBool; 10] = [AtomicBool::new(false); 10];

but I'm getting the error

error[E0277]: the trait bound `core::sync::atomic::AtomicBool: core::marker::Copy` is not satisfied
. . .
the trait `core::marker::Copy` is not implemented for `core::sync::atomic::AtomicBool`
    |
    = note: the `Copy` trait is required because the repeated element will be copied

How to correctly define arrays with types which do not implement Copy?

List out every item:

static ELEMENT_EXISTS: [AtomicBool; 10] = [AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false), AtomicBool::new(false), ];

@jer, yeah, I thought about it, but what if I had not 10, but 100 elements? Is there some more compact way to do it?

The [val; N] syntax requires Copy, there's no way around it (it creates the element once, then copies it for every element in the array).
There might be a way to define it with a macro (though counting is hard).
And then there's the array-init crate for exactly that use case.

But at that point I would also question why you need a static array of that many items to begin with.

I'm learning embedded and I have 53 GPIO pins on board, so as an excercise to practice I'm trying to implement the Singleton approach suggested to me for all that 53 pins

Using unsafe is one way but would personally just stick to safe (eg vec) if not needing performance.

Considering that 53 is less than 64, you can use an AtomicU64 as shown here.

2 Likes

You can use the ::array_init::array_init! macro, which under the hood uses the unsafe @jonh suggested, except that it using it does not require you to use unsafe, meaning that it is sound to use (until my (ignored) PR gets merged, this macro's only flaw is that it can leak memory if the construction of the array panics, but since AtomicBool::new cannot panic this is fine):

//! [dependencies]
//! array-init = "0.1.0"

static ELEMENT_EXISTS: [AtomicBool; 53] =
    ::array_init::array_init!(|_| AtomicBool::new(false))
;