2016-09-20 5 views
5

मैं एक ही टुकड़ा के शीर्ष पर एक टुकड़ा का अंत लिखना चाहता हूं।मैं स्लाइस से उसी स्लाइस में डेटा कैसे लिख सकता हूं?

let mut foo = [1, 2, 3, 4, 5]; 

foo[..2].copy_from_slice(&[4..]); // error: multiple references to same data (mut and not) 

assert!(foo, [4, 5, 3, 4, 5]); 

मैं How to operate on 2 mutable slices of a Rust array

देखा है मैं चाहता हूँ अधिकतम प्रदर्शन संभव (उदाहरण के लिए, foo.as_ptr() का उपयोग करके)।

+0

दुर्भाग्यवश ऐसा लगता है कि एक समारोह समान नहीं है 'संग्रह' करने के लिए जो एक इटरेटर से 'IterMut' भरता है। – starblue

+1

यह भी देखें [एक टुकड़ा की मूर्खतापूर्वक प्रतिलिपि कैसे करें?] (Http://stackoverflow.com/q/28219231/155423) – Shepmaster

उत्तर

2

मैं मैं क्या चाहते हो के लिए एक बेहतर रास्ता मिल गया:

fn main() { 
    let mut v = [1, 2, 3, 4, 5, 6]; 

    // scoped to restrict the lifetime of the borrows 
    { 
     let (left, right) = v.split_at_mut(3); 
     assert!(left == [1, 2, 3]); 
     assert!(right == [4, 5, 6]); 
     for (l, r) in left.iter_mut().zip(right) { 
      *l = *r; 
     } 
    } 

    assert!(v == [4, 5, 6, 4, 5, 6]); 
} 
7

सामान्य रूप से एक स्लाइस के अंदर एक श्रेणी से डेटा की प्रतिलिपि बनाने के लिए (ओवरलैप की अनुमति देता है), हम .split_at_mut() का भी उपयोग नहीं कर सकते हैं।

मैं मुख्य रूप से अन्यथा .split_at_mut() का उपयोग करूंगा। (, वहाँ कुछ भी आपको लगता है सीमा की जांच ताकि अनुकूलन की? इसके अलावा नहीं जा रहा है बनाता है यदि आपके पास पर्याप्त डेटा की प्रतिलिपि है कि यह तुलना में थोड़ा-बहुत असर है कर रहे हैं?)

वैसे भी, यह है आप कैसे लपेट सकता है std::ptr::copy (ओवरलैप है प्रतिलिपि, उर्फ ​​memmove) एक सुरक्षित या unsafe समारोह में।

use std::ptr::copy; 
use std::ops::Range; 

/// Copy the range `data[from]` onto the index `to` and following 
/// 
/// **Panics** if `from` or `to` is out of bounds 
pub fn move_memory<T: Copy>(data: &mut [T], from: Range<usize>, to: usize) { 
    assert!(from.start <= from.end); 
    assert!(from.end <= data.len()); 
    assert!(to <= data.len() - (from.end - from.start)); 
    unsafe { 
     move_memory_unchecked(data, from, to); 
    } 
} 

pub unsafe fn move_memory_unchecked<T: Copy>(data: &mut [T], from: Range<usize>, to: usize) { 
    debug_assert!(from.start <= from.end); 
    debug_assert!(from.end <= data.len()); 
    debug_assert!(to <= data.len() - (from.end - from.start)); 
    let ptr = data.as_mut_ptr(); 
    copy(ptr.offset(from.start as isize), 
     ptr.offset(to as isize), 
     from.end - from.start) 
} 

fn main() { 
    let mut data = [0, 1, 2, 3, 4, 5, 6, 7]; 
    move_memory(&mut data, 2..6, 0); 
    println!("{:?}", data); 
    move_memory(&mut data, 0..3, 5); 
    println!("{:?}", data); 
} 

Playground link

+0

जंग में शुरुआती होने के नाते मैं पूछ सकता हूं कि किस प्रकार वेक्टर तत्व ड्रॉप इस मामले में टाइप टी के प्रकार के लिए काम करेगा टी ड्रॉप ट्राइट लागू करता है? –

+1

ज़रूर। 'टी: कॉपी' का अर्थ है कि' टी' तुच्छ रूप से प्रतिलिपि योग्य है (बाइट-बाय-बाइट) और इसका मतलब यह भी है कि 'टी' में विनाशक नहीं हो सकता है। तो हमें यहां ड्रॉप के बारे में चिंता करने की ज़रूरत नहीं है। (इस जवाब में कोई वेक्टर भी नहीं है, केवल एक परिवर्तनीय टुकड़ा)। – bluss

+0

आह हाँ ने कॉपी बाधा को नोटिस नहीं किया था। धन्यवाद। –

2

अपने प्रकार Copyऔर subslices लागू करते हैं तो ओवरलैपिंग नहीं हैं:

fn main() { 
    let mut v = [1, 2, 3, 4, 5, 6]; 

    { 
     let (left, right) = v.split_at_mut(3); 
     // Perform further work to ensure slices are the same length, as needed 
     left.copy_from_slice(right); 
    } 

    assert!(v == [4, 5, 6, 4, 5, 6]); 
} 
+0

यदि दो स्लाइसों के अलग-अलग आकार होते हैं, तो फ़ंक्शन घबराएगा और मेरे मामले में मैं उसी टुकड़े के सामने 5 अंतिम बाइट्स कॉपी करना चाहता हूं ... – Kerollmops

+1

@ केरोसिन हाँ, इसलिए मैंने टिप्पणी डाली * "स्लाइस सुनिश्चित करें एक ही लंबाई हैं "*।^_ ^ – Shepmaster

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