为什么ops :: Range <t>不实现复制,即使T是复制?

时间:2017-04-14 18:10:42

标签: rust

最近,我想为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,即使TCopy,也就是f32为什么会这样?我认为Range<T>只是一对T?所以它肯定可以实现Copy

1 个答案:

答案 0 :(得分:7)

因为Range<T>经常用作迭代器,并且迭代器为Copy was discovered to be a footgunOne specific example与认为迭代器是先进的有关,而实际上它是一个先进的副本:

for x in it {  // a *copy* of the iterator is used here
    // ..
}

match it.next() {  // the original iterator is used here
    // ..
}

Another example

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。提出了一个潜在的解决方法:

  

范围字段是公共的,您可以在构造函数/函数边界将它们重新打包成可复制的元组(或等效的)

另见: