fn main() {
let s1: [Option<String>; 26] = [None; 26];
}
在 Rust 中陣列的型別使用 [TYPE; LENGTH],並且可以用 [EXPR; LENGTH] 來進行初始化。
這段程式編譯後會得到以下錯誤。
let s1: [Option<String>; 26] =
[None; 26];
^^^^ the trait `Copy` is not implemented for `String`
至於原因可以把以上的 Code 展開為
s1[0] = None; s1[1] = None; ... s1[25] = None;
因此會要求 [EXPR; LENGTH] 中的 EXPR 需要有 Copy Trait,否則會 Move 導致 s1[1] 以後無法被執行。而 Option<String> 中的 String 無法 Move,因此導致 Option<String> 也無法 Move。
雖然 Option::<String>::None 是不含 String,但 Some, None 都是 enum Option 中的一員,無法通過 Trait Bound 檢查可以理解。但以上的檢查有個意外的繞過方法:使用 const。
fn main() {
const NONE: Option<String> = None;
let s1: [Option<String>; 26] = [NONE; 26];
}
const 在 Rust 中表示其值會在編譯期間就決定,而非執行時計算。由於編譯期間就確定 [NONE; 26]中的 None 不可能是 Some,於是檢查就通過了...
[EXPR; LENGTH] 中 Expr 需要符合以下條件之一
- 有實做 Copy Trait
- 是 const
沒有留言:
張貼留言