I'm using const generics as parameter to illustrate an array type:
struct Foo<const I: usize> {
i: [Option<Arc<i32>>;I],
}
impl<const I: usize> Foo<I> {
fn get() -> Self {
Foo {
i: [None;I]
}
}
}
But the code will not compile, it said that Arc<i32>
needs to implement copy trait:
error[E0277]: the trait bound `Arc<i32>: Copy` is not satisfied
--> src/main.rs:10:17
|
10 | i: [None;I]
| ^^^^ the trait `Copy` is not implemented for `Arc<i32>`
|
= note: required for `Option<Arc<i32>>` to implement `Copy`
= note: the `Copy` trait is required because this value will be copied for each element of the array
I seem to know why it needs copy trait for an array initialization, but in my case I only initiate with None
, so is there any chance my code could work?
I think you should be able to use std::array::from_fn
to do what you need
4 Likes
Another alternative is to use a constant: Array expressions allow initialization with the value of a const
item, so this will work:
impl<const I: usize> Foo<I> {
fn get() -> Self {
const NONE: Option<Arc<i32>> = None;
Foo {
i: [NONE; I]
}
}
}
eventually, this could be simplified when we get const { … }
expressions, to
impl<const I: usize> Foo<I> {
fn get() -> Self {
Foo {
i: [const { None }; I],
}
}
}
I suppose one (main) advantage of this over array::from_fn
is that this allows you to make fn get()
itself a const fn
, too. Other than that, array::from_fn
is probably more readable (than the approach using a const
item) and (I assume) shouldn’t make a difference in terms of performance.
6 Likes
It seems that inline_const is an unstable feature and I never know it before, learns every day
I like this solution because it allows get
function to be a const function.
Hopefully soon™! It's in p-FCP and the two concerns that were raised have been resolved: Stabilise inline_const by nbdd0121 · Pull Request #104087 · rust-lang/rust · GitHub
So maybe it'll make Rust 1.69.0 on 4/20.
2 Likes