2015-07-11 3 views
14

मुझे एक निश्चित लंबाई सरणी शुरू करने में परेशानी हो रही है। My attempts so far all result in the same "use of possibly uninitialized variable: foo_array" error:एक निश्चित लंबाई सरणी शुरू करने का सही तरीका क्या है?

#[derive(Debug)] 
struct Foo { a: u32, b: u32 } 

impl Default for Foo { 
    fn default() -> Foo { Foo{a:1, b:2} } 
} 

pub fn main() { 
    let mut foo_array: [Foo; 10]; 

    // Do something here to in-place initialize foo_array? 

    for f in foo_array.iter() { 
     println!("{:?}", f); 
    } 
} 
error[E0381]: use of possibly uninitialized variable: `foo_array` 
    --> src/main.rs:13:14 
    | 
13 |  for f in foo_array.iter() { 
    |    ^^^^^^^^^ use of possibly uninitialized `foo_array` 

मैं Default विशेषता लागू किया, लेकिन जंग डिफ़ॉल्ट एक सी ++ निर्माता के सदृश द्वारा इस कॉल करने के लिए प्रतीत नहीं होता।

एक निश्चित लंबाई सरणी प्रारंभ करने में उचित तरीका क्या है? मैं किसी प्रकार की प्रतिलिपि के बजाय एक कुशल इन-प्लेस प्रारंभ करना चाहता हूं।

संबंधित: Why is the Copy trait needed for default (struct valued) array initialization?

संबंधित: Is there a way to not have to initialize arrays twice?

+2

* जंग डिफ़ॉल्ट * द्वारा इस कॉल करने के लिए प्रतीत नहीं होता है - यह सही है: यू arrayvec crate उपयोग कर सकते हैं । किसी भी विशेष तरीके से कंपाइलर द्वारा 'डिफ़ॉल्ट' विशेषता का उपयोग नहीं किया जाता है। यह केवल प्रोग्रामर के लिए उपयोग है। – Shepmaster

उत्तर

11

सुरक्षित लेकिन somewhat inefficient solution:

#[derive(Copy, Clone, Debug)] 
struct Foo { a: u32, b: u32 } 

fn main() { 
    let mut foo_array = [Foo { a: 10, b: 10 }; 10]; 
} 

आप विशेष रूप से a solution without copies के लिए पूछ रहे हैं के बाद से:

use std::mem; 
use std::ptr; 

#[derive(Debug)] 
struct Foo { a: u32, b: u32 } 

// We're just implementing Drop to prove there are no unnecessary copies. 
impl Drop for Foo { 
    fn drop(&mut self) { 
     println!("Destructor running for a Foo"); 
    } 
} 

pub fn main() { 
    let array = unsafe { 
     // Create an uninitialized array. 
     let mut array: [Foo; 10] = mem::uninitialized(); 

     for (i, element) in array.iter_mut().enumerate() { 
      let foo = Foo { a: i as u32, b: 0 }; 

      // Overwrite `element` without running the destructor of the old value. 
      // Since Foo does not implement Copy, it is moved. 
      ptr::write(element, foo) 
     } 

     array 
    }; 

    for element in array.iter() { 
     println!("{:?}", element); 
    } 
} 
+0

@ एबी .: पहला समाधान अक्षम क्यों है? (बेवकूफ सवाल, मुझे वास्तव में कोई जानकारी नहीं है ...) –

+0

यह उन मामलों में अक्षम है जहां आपको एक सरणी बनाने की आवश्यकता है जिसमें तत्व एक-दूसरे से भिन्न होते हैं, पोकर कार्ड के सेट कहते हैं। एक मानक 52 कार्ड सेट में आप 51 अनावश्यक प्रतियां कर सकते हैं। –

+4

आप किसी भी() 'और' मेम करने के लिए कॉल के बीच आतंक का मौका :: अप्रारंभीकृत बिंदु है जहां सरणी पूरी तरह से आरंभ है, तो इस कोड को टूट गया है और सुरक्षित घबराओ। यदि फू एक "पीओडी" प्रकार है तो यह ठीक है, हालांकि। ध्यान दें कि जैसे ही आप जेनेरिक (और प्रारंभिक लूप में गुणों की विशेषता के लिए कॉल करते हैं) शुरू करते हैं, तो आपके पास अब आतंक की कमी की गारंटी देने का कोई तरीका नहीं है। – bluss

0

यो

Cargo.toml

[package] 
name = "initialize_array" 
version = "0.1.0" 
authors = ["author"] 

[dependencies] 
arrayvec = "0.3.20" 

src/main.rs

extern crate arrayvec; 

use arrayvec::ArrayVec; 
use std::iter; 

#[derive(Clone)] 
struct Foo { 
    a: u32, 
    b: u32, 
} 

fn main() { 
    let foo_array: [Foo; 10] = iter::repeat(Foo { a: 10, b: 10}) 
     .collect::<ArrayVec<_>>() 
     .into_inner() 
     .unwrap_or_else(|_| unreachable!()); 
} 
संबंधित मुद्दे