Why doesn't ops::Range<T> implement Copy, even if T is Copy?

强颜欢笑 提交于 2020-08-01 09:53:51

问题


Recently, I wanted to write a type holding parameters for a 3D projection:

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,       
}

However, I got this error:

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`

So apparently, Range<T> never implements Copy, even if T is Copy, like f32 is. Why is that? I thought a Range<T> would just be a pair of Ts? So it surely could implement Copy?


回答1:


Because Range<T> is often used as an iterator, and having iterators be Copy was discovered to be a footgun. One specific example had to do with thinking that an iterator was advanced, when in reality it was a copy that was advanced:

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);
    }
}

And another that prompted a question: Using the same iterator multiple times in Rust

It was believed that having iterators be explicitly copied via clone helped prevent these cases


Specifically re-adding Copy to Range was proposed and rejected. A potential workaround was suggested:

Range fields are public, you can repack them into a copyable tuple (or equivalent) at the constructor/function boundary

See also:

  • Why are iterators not copyable?
  • Re-using a range for iteration


来源:https://stackoverflow.com/questions/43416914/why-doesnt-opsranget-implement-copy-even-if-t-is-copy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!