最近,我想为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,
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到了这个错误:
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`
Run Code Online (Sandbox Code Playgroud)
显然,Range<T>
从来没有实现Copy
,即使T
是Copy
,就像f32
是.这是为什么?我以为Range<T>
只是一对T
s?所以它肯定可以实现Copy
?
因为Range<T>
经常被用作迭代器,所以Copy
发现迭代器是一个步枪.一个具体的例子与认为迭代器是高级的有关,而实际上它是一个高级的副本:
for x in it { // a *copy* of the iterator is used here
// ..
}
match it.next() { // the original iterator is used here
// ..
}
Run Code Online (Sandbox Code Playgroud)
fn main() {
let stream = "Hello, world!".chars().cycle();
for _ in 0..10 {
let chunk: String = stream.take(3).collect();
println!("{}", chunk);
}
}
Run Code Online (Sandbox Code Playgroud)
另一个提示一个问题:在Rust中多次使用相同的迭代器
人们认为通过明确复制迭代器clone
有助于防止这些情况
特别重新添加Copy
到Range
提议和拒绝.提出了一个潜在的解决方法:
范围字段是公共的,您可以在构造函数/函数边界将它们重新打包为可复制的元组(或等效元组)
也可以看看: