![](/img/trans.png)
[英]Why can't generic methods choose a specific method when the generic one doesn't match?
[英]Why can't None be cloned for a generic Option<T> when T doesn't implement Clone?
給定一個帶有泛型Option<T>
的結構,其中T
可能無法實現Clone
為什么不能克隆None
? T
類型的None
與其他任何None
一樣嗎? 例如:
struct Foo<T> {
bar: Vec<Option<T>>,
}
impl <T> Foo<T> {
fn blank(size: usize) -> Foo<T> {
Foo {
bar: vec![None; size],
}
}
}
正如其他答案正確指出的那樣,這是由於vec!
-宏已實施。 您可以手動創建任何Option<T>
的Vec
,而無需將T
設為Clone
:
let bar = std::iter::repeat_with(|| Option::<T>::None).take(size).collect::<Vec<_>>();
這將創建size
-number of Option::<T>::None
並將它們放在Vec
中,這將被預先分配到適當的大小。 這適用於任何T
。
如果一個部分不能被克隆,那么任何部分都不能被克隆。 從類型的角度考慮這一點:您有一個名為foo
的Option<T>
類型的變量,其中T
不可克隆。 當然, None
可以被克隆,但Some(_)
不能,並且變量的類型不會告訴你它是什么。 因此,從編譯時的角度來看,您無法克隆該選項。
T
類型的None
與其他任何None
一樣嗎?
絕對不是,與 null 通常實現為空引用的基於引用的語言不同,Rust 的Option<T>
不引入間接方法,並且在選項為Some
時將T
內聯存儲。 由於所有枚舉變體具有相同的大小,因此None
變體仍必須至少占用與T
一樣多的空間。
話雖如此,從技術上講,可以在沒有T
被Clone
的情況下克隆None
值是正確的,因為枚舉的None
變體不包含T
,它只存儲鑒別器並保留可能包含T
的空間,如果變體是更改為Some
。 但由於 Rust 枚舉變體不是單獨的類型,因此為枚舉定義的特征綁定必須涵蓋所有變體。
請參閱其他答案更詳細的解釋和說明如何創建不可克隆Option
的None
值的向量。
Option
只能在內部T
實現Clone
時被克隆:
impl<T> Clone for Option<T>
where
T: Clone,
T
類型的None
與其他任何None
一樣嗎?
實際上,沒有。 Rust 編譯器甚至不將None
視為一種類型。 相反, None
只是Option<T>
的變體(子類型)。 嘗試比較兩個不同T
的None
:
let a: Option<String> = None;
let b: Option<u8> = None;
assert_eq!(a, b)
你會看到它們實際上是完全不相關的類型:
error[E0308]: mismatched types
--> src/main.rs:4:5
|
4 | assert_eq!(a, b)
| ^^^^^^^^^^^^^^^^ expected struct `String`, found `u8`
|
= note: expected enum `Option<String>`
found enum `Option<u8>`
所以 Rust 編譯器實際上將None
視為Option::<T>::None
。 這意味着如果T
不是Clone
,則Option<T>
不是Clone
,因此Option::<T>::None
不能是Clone
。
要使您的代碼編譯,您必須將T
限制為Clone
:
struct Foo<T: Clone> {
bar: Vec<Option<T>>,
}
impl <T: Clone> Foo<T> {
fn blank(size: usize) -> Foo<T> {
Foo {
bar: vec![None; size],
}
}
}
現在編譯器知道T
是Clone
,並且實現了Option<T>
(和Option::<T>::None
)的Clone
實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.