![](/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.