2017-04-14 10 views
6

हाल ही में, मैं एक प्रकार एक 3 डी प्रक्षेपण के लिए मानकों को पकड़े लिखना चाहते थे:क्यों नहीं करता है :: श्रेणी <T> कॉपी लागू करें, भले ही टी कॉपी हो?

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 लागू कर सकता है?

+2

मुझे यकीन है कि मैं पहले इस सवाल को देखा है हूँ ... लेकिन निश्चित रूप से नहीं कर सकते हैं इसे फिर से ढूंढें। मैंने पाया सबसे नज़दीकी संभावित डुप्लिकेट http://stackoverflow.com/questions/31045637/re-using-a-range-for-iteration था। मुझे याद है कि इसे लागू नहीं किया गया था क्योंकि ऐसे मामले थे जहां यह भ्रमित हो सकता है: https://github.com/rust-lang/rust/issues/18045 –

उत्तर

7

क्योंकि Range<T> अक्सर एक पुनरावर्तक के रूप में उपयोग किया जाता है, और iterators Copywas discovered to be a footgun होने के कारण होता है।

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

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

Another example: One specific 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 के माध्यम से स्पष्ट रूप से कॉपी किया गया है इन मामलों को रोकने में मदद मिली


विशेष रूप से फिर से जोड़ने Rangewas proposed and rejected करने के लिए Copy। एक संभावित समाधान का सुझाव दिया गया था:

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

यह भी देखें:

संबंधित मुद्दे