Generics 为什么可以';t不能克隆通用选项<;T>;当T不';不实施克隆?
给定一个带有泛型Generics 为什么可以';t不能克隆通用选项<;T>;当T不';不实施克隆?,generics,rust,clone,Generics,Rust,Clone,给定一个带有泛型选项的结构,其中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; s
选项的结构,其中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],
}
}
}
structfoo{
酒吧:Vec,
}
impl-Foo{
fn空白(尺寸:usize)->Foo{
福{
条形图:vec![无;大小],
}
}
}
如果一个部件不能克隆,那么就不能克隆任何部件。从类型的角度考虑这一点:您有一个名为foo
的变量,其类型为Option
,其中T
是不可克隆的。当然,None
可以克隆,但是Some()
不能克隆,并且变量的类型不会告诉您它是哪个。因此,从编译时的角度来看,您不能克隆该选项。只有当内部t
实现克隆时,选项才能克隆:
let bar = std::iter::repeat_with(|| Option::<T>::None).take(size).collect::<Vec<_>>();
impl克隆选项
哪里
T:克隆,
类型为t
的None
不是与任何其他None
相同吗
实际上,不是。Rust编译器甚至不将None
视为一个类型。相反,None
只是选项
的一个变体(子类型)。尝试比较两个不同的T
s的None
s:
设a:Option=None;
设b:Option=None;
断言!(a、b)
您将看到它们实际上是完全不相关的类型:
错误[E0308]:类型不匹配
-->src/main.rs:4:5
|
4 |断言| eq!(a、b)
|^^^^^^^^^^^^^^^^^^^^^^^^应为结构“String”,找到“u8”`
|
=注意:应为enum`选项`
找到enum`选项`
因此,Rust编译器实际上将None
视为选项:::None
。这意味着如果T
不是Clone
,那么选项
就不是Clone
,因此选项:::None
不能是Clone
要使代码编译,必须将T
约束为Clone
:
let bar = std::iter::repeat_with(|| Option::<T>::None).take(size).collect::<Vec<_>>();
structfoo{
酒吧:Vec,
}
impl-Foo{
fn空白(尺寸:usize)->Foo{
福{
条形图:vec![无;大小],
}
}
}
现在编译器知道T
是Clone
,并且选项的Clone
(和选项::::无)的实现已经完成。其他答案正确地指出了ouf,这是由于vec的方式代码>-宏已实现。您可以手动创建任何选项的Vec
,而无需T
成为Clone
:
let bar = std::iter::repeat_with(|| Option::<T>::None).take(size).collect::<Vec<_>>();
let bar=std::iter::使用(| |选项::::无)重复_)。获取(大小)。收集::();
这将创建大小
-选项编号:::无
,并将它们放置在Vec
中,该Vec将预先分配到适当的大小。这适用于任何T
类型为t
的None
不是与任何其他None
相同吗
绝对不是!与基于引用的语言不同,在基于引用的语言中,null通常被实现为null引用,而Rust的选项
不引入间接寻址,当选项为Some
时,它将T
内联存储。由于所有枚举变量都具有相同的大小,None
变量必须至少占用与T
相同的空间
话虽如此,从技术上讲,None
值可以在T
不为Clone
的情况下克隆,这是正确的,因为枚举的None
变量不包含T
,它仅存储鉴别器,并保留可能包含T
的空间(如果变量更改为Some
)。但是,由于Rust枚举变量不是单独的类型,因此为枚举定义的特征绑定必须覆盖所有变量
参见其他答案更详细的解释和说明如何创建不可克隆的选项的None
值的向量“类型t
的None
与任何其他None
相同吗?”-不,None
是选项的变体。它的全名应该是选项:::None
,但您通常不需要它,因为类型通常是推断出来的。您链接的RFC与手头的问题没有任何关系:变体类型可能没有固有的impl,或者实现的特征。@IbraheemAhmed如果我理解正确,就没有类型理论的理由说明不能克隆None
,但是静态分析器还没有这个功能。正确吗?@HiDefender好吧,类型理论的原因是枚举变量实际上不是类型。相反,它们是枚举的变体(子类型),其行为由包含它们的枚举决定。Rust编译器查看枚举变量的方式将来可能会改变,也可能不会改变。@HiDefender我更新了我的问题,使之更清楚。@Shepmaster更新了。补充说明:您只需使用repeat_with(| | None)
,它是一个选项,可以推断出。为了清楚起见。