最近,我想为3D投影编写一个类型保持参数:
use std::ops::Range;
#[derive(Clone, Copy)]
struct CamProj {
/// Near and far plane
proj_range: Range<f32>,
/// Field of view
fov: cgmath::Rad<f32>, // `Rad` derives `Copy`
/// Width divided by height
aspect_ratio: f32,
}
但是,我收到了这个错误:
error[E0204]: the trait `Copy` may not be implemented for this type
--> <anon>:3:21
|
3 | #[derive(Clone, Copy)]
| ^^^^
...
6 | proj_range: Range<f32>,
| ---------------------- this field does not implement `Copy`
显然,Range<T>
从未实现Copy
,即使T
为Copy
,也就是f32
。 为什么会这样?我认为Range<T>
只是一对T
?所以它肯定可以实现Copy
?
答案 0 :(得分:7)
因为Range<T>
经常用作迭代器,并且迭代器为Copy
was discovered to be a footgun。 One specific example与认为迭代器是先进的有关,而实际上它是一个先进的副本:
for x in it { // a *copy* of the iterator is used here
// ..
}
match it.next() { // the original iterator is used here
// ..
}
fn main() {
let stream = "Hello, world!".chars().cycle();
for _ in 0..10 {
let chunk: String = stream.take(3).collect();
println!("{}", chunk);
}
}
另一个提示问题:Using the same iterator multiple times in Rust
相信通过clone
显式复制迭代器有助于防止这些情况
专门将Copy
重新添加到Range
was proposed and rejected。提出了一个潜在的解决方法:
范围字段是公共的,您可以在构造函数/函数边界将它们重新打包成可复制的元组(或等效的)
另见: