Option<Box<Thing>>
ある種の の のような、null 可能でコピー不可能な型の固定サイズの配列を初期化しようとしていますThing
。 余分な間接参照なしで、そのうちの 2 つを構造体にパックしたいと思います。 次のように記述します。
let array: [Option<Box<Thing>>; SIZE] = [None; SIZE];
しかし、構文ではが を実装する[e; n]
必要があるため、動作しません。もちろん、 を に拡張することもできますが、 が大きい場合は扱いにくくなります。 の不自然なエンコードなしでマクロを使用してこれを行うことはできないと思います。これを行う良い方法はありますか?e
Copy
SIZE
None
SIZE
SIZE
はい、 を使えば簡単ですunsafe
。 を使わずにこれを行う方法はありますかunsafe
?
ベストアンサー1
Rust 1.79 (2024 年 6 月にリリース予定) では、これを簡単に行うには、インライン const を使用します。
struct Thing;
fn main() {
const SIZE: usize = 100;
let _array: [Option<Box<Thing>>; SIZE] = [const {None}; SIZE];
}
これは変数の初期化にも機能しますstatic
。
Rust 1.63(2022年8月リリース)では、以前投稿された回答よりもクリーンな代替案が以下を使用して可能になりました。std::array::from_fn()
:
const SIZE: usize = 100;
let array: [Option<Box<Thing>>; SIZE] = std::array::from_fn(|_| None);
1.63 より前のバージョンの Rust をサポートする必要がある場合、または を初期化する必要がある場合はstatic
、中間初期化子を使用する別の方法がconst
Rust 1.38 (2019 年 9 月リリース) 以降で機能します。
const SIZE: usize = 100;
const INIT: Option<Box<Thing>> = None; // helper
// also works with static array
let array: [Option<Box<Thing>>; SIZE] = [INIT; SIZE];
最初のアプローチと最後のアプローチには、配列項目がコンパイル時に評価できる表現 (定数、列挙型バリアント、空の Vec または String、またはそれらで構成されるプリミティブ コンテナー (列挙型、タプル)) を持つ必要があるという制限があります。None
または数値のタプルは機能しますが、空でないVec
またははString
機能しません。このarray::from_fn()
アプローチにはそのような制限はありません。
Box
上記の例はすべて、 ;の有無にかかわらず機能します。を使用するのBox
は、質問で ; が使用されているためです。すべて、任意のサイズの配列で機能します。