2015-01-15 6 views
6

मैं Vec में विशेषता वस्तुओं का उपयोग करना चाहता हूं। सी ++ में मैं बेस क्लास Thing बना सकता हूं, जिसमें से Monster1 और Monster2 व्युत्पन्न किया गया है। मैं फिर std::vector<Thing*> बना सकता था। Thing ऑब्जेक्ट्स को कुछ डेटा उदास करना होगा उदा। x : int, y : int, लेकिन व्युत्पन्न कक्षाओं को और डेटा जोड़ने की आवश्यकता है।मैं ऑब्जेक्ट्स का एक विषम संग्रह कैसे बना सकता हूं?

वर्तमान में मैं मैं get_thing_record(), attack(), make_noise() आदि के लिए तरीके के साथ एक ThingTrait को परिभाषित करने और उन्हें Monster1 और Monster2 के लिए लागू की तरह

struct Level { 
    // some stuff here 
    pub things: Vec<Box<ThingTrait + 'static>>, 
} 

struct ThingRecord { 
    x: i32, 
    y: i32, 
} 

struct Monster1 { 
    thing_record: ThingRecord, 
    num_arrows: i32, 
} 

struct Monster2 { 
    thing_record: ThingRecord, 
    num_fireballs: i32, 
} 

कुछ है।

+1

अगर अपने राक्षसों ज्यादातर पहले से जाना जाता है (यानी अपने एक खेल इंजन हर किसी को एक नया राक्षस बनाने के लिए अनुमति देता है बनाने नहीं) आप वैकल्पिक रूप से एक enum –

+5

साथ काम कर सकता था यह भी देखें [reddit पर चर्चा] (http://www.reddit.com/r/rust/comments/2sh28k/best_way_to_implement_heterogeneous_collection_of/)। (बीटीडब्ल्यू, यदि कोई प्रश्न पार करना है, तो आमतौर पर उनके बीच कम से कम लिंक करने के लिए विनम्र होता है ताकि उदासीन लोग चर्चा पर ध्यान न दें।) – huon

+0

ठीक है। मैं लक्षणों और एक विधि का उपयोग करने के बीच फाड़ा हूं जो साझा डेटा देता है ... या बस सब कुछ के लिए एक enum का उपयोग कर। मैं सोच रहा हूं कि पूर्व दो बुराइयों में से कम है। यदि विरासत भाषा में जोड़ा जा रहा है, तो यह कैसा दिख रहा है? इसके अलावा सी ++ से मुझे कुछ भी याद नहीं है। ताज़ी हवा का झोंका। – stevenkucera

उत्तर

8

एक विषम संग्रह (इस मामले में एक सदिश) लागू करने के लिए सबसे एक्स्टेंसिबल तरह से वस्तुओं की ठीक है तुम्हारे पास क्या है:

Vec<Box<ThingTrait + 'static>> 

हालांकि कई बार जहां एक जीवन भर है कि 'static नहीं है चाहते हो सकता है, इसलिए आप की तरह कुछ आवश्यकता होगी:

Vec<Box<ThingTrait + 'a>> 

तुम भी बॉक्स्ड लक्षण के बजाय, संदर्भ लक्षण के का एक संग्रह हो सकता है:

Vec<&ThingTrait> 
एक उदाहरण

:

trait ThingTrait { 
    fn attack(&self); 
} 

impl ThingTrait for Monster1 { 
    fn attack(&self) { 
     println!("monster 1 attacks") 
    } 
} 

impl ThingTrait for Monster2 { 
    fn attack(&self) { 
     println!("monster 2 attacks") 
    } 
} 

fn main() { 
    let m1 = Monster1 { 
     thing_record: ThingRecord { x: 42, y: 32 }, 
     num_arrows: 2, 
    }; 

    let m2 = Monster2 { 
     thing_record: ThingRecord { x: 42, y: 32 }, 
     num_fireballs: 65, 
    }; 

    let things: Vec<Box<ThingTrait>> = vec![Box::new(m1), Box::new(m2)]; 
} 

टिप्पणी में उल्लेख किया है, एक कम ओपन एंडेड समाधान एक enum उपयोग करने के लिए है। इस की आवश्यकता नहीं है कि मूल्यों Box एड हो:

enum Monster { 
    One(Monster1), 
    Two(Monster2), 
} 

impl Monster { 
    fn attack(&self) { 
     match *self { 
      Monster::One(_) => println!("monster 1 attacks"), 
      Monster::Two(_) => println!("monster 2 attacks"), 
     } 
    } 
} 

fn main() { 
    let m1 = Monster1 { 
     thing_record: ThingRecord { x: 42, y: 32 }, 
     num_arrows: 2, 
    }; 

    let m2 = Monster2 { 
     thing_record: ThingRecord { x: 42, y: 32 }, 
     num_fireballs: 65, 
    }; 

    let things = vec![Monster::One(m1), Monster::Two(m2)]; 
} 
संबंधित मुद्दे