2015-06-15 3 views
6

जंग के लिए एक सीखने की परियोजना के रूप में, मेरे पास एक सिंगल लिंक्ड सूची का एक बहुत ही सरल (काम करने वाला, अगर अधूरा) कार्यान्वयन है। structs की घोषणा इस तरह दिखता है:पूंछ सूचक के साथ एक लिंक्ड सूची लिखने का बेवकूफ तरीका क्या है?

type NodePtr<T> = Option<Box<Node<T>>>; 

struct Node<T> { 
    data: T, 
    next: NodePtr<T>, 
} 

pub struct LinkedList<T> { 
    head: NodePtr<T>, 
} 

को लागू करने size और push_front दोनों यथोचित सीधी-सपाट थे, हालांकि कर आकार iteratively शामिल था कुछ "उधार चेकर के साथ लड़ रहे हैं।"

अगली चीज़ जो मैं कोशिश करना चाहता था tail पॉइंटर LinkedList संरचना में जोड़ रहा था। एक कुशल push_back ऑपरेशन सक्षम करने के लिए। यहाँ मैं एक दीवार में भाग गया है। पहले मैंने Option<&Box<Node<T>>> और फिर Option<&Node<T>> का उपयोग करने का प्रयास किया। उन दोनों ने 'a एस हर जगह छिड़कने का नेतृत्व किया, लेकिन अंत में जीवन भर के चेकर का वादा करने में असमर्थ रहा कि tail मान्य होगा।

मैं के बाद से जांच निष्कर्ष यह है कि यह इन परिभाषाओं के साथ असंभव है के लिए आए हैं: गारंटी संकलक कि tail स्थानों मुझे लगता है कि यह मान्य है में मान्य होगा करने के लिए कोई रास्ता नहीं है कि वहाँ। एकमात्र तरीका यह है कि मैं संभवतः यह पूरा कर सकता हूं कि मेरे सभी पॉइंटर्स Rc<_> या Rc<RefCell<_>> हो, क्योंकि वे एक ही ऑब्जेक्ट (अंतिम नोड) पर इंगित करने वाली दो चीजें रखने का एकमात्र सुरक्षित तरीका हैं।

मेरा प्रश्न: क्या यह सही निष्कर्ष है? अधिक आम तौर पर: डेटा संरचनाओं के अंदर अज्ञात पॉइंटर्स के लिए बेवकूफ जंग समाधान क्या है? मेरे दिमाग में, संदर्भ गिनती इतनी सरल के लिए भारी वजन लगती है, इसलिए मुझे लगता है कि मुझे कुछ याद आना चाहिए। (या शायद मैं सिर्फ मेरे मन स्मृति सुरक्षा के लिए सही मानसिकता में अभी तक मिल गया है नहीं।)

+2

आप सही हैं; 'आरसी' जैसी चीजों द्वारा प्रदान किए गए साझा स्वामित्व के बिना सुरक्षित जंग में चक्रों को व्यक्त करना संभव नहीं है। –

+0

यह मेरे प्रश्न का सही उत्तर जैसा दिखता है, लेकिन मैं वास्तव में साझा स्वामित्व साझा नहीं करना चाहता हूं। मुझे लगता है कि मैं 'आरसी' के अलावा 'std :: rc :: कमजोर' के साथ कुछ खेल रहा हूं, क्योंकि मैंने अभी देखा है कि पूर्व मौजूद है। शीघ्र जवाब देने के लिए ध्न्यवाद! – GrandOpener

+1

* मेरे दिमाग में, संदर्भ गिनती इतनी सरल * => के लिए बहुत भारी वजन लगती है जब आप स्वामित्व के मुद्दों (जो डेटा के प्रत्येक टुकड़े का मालिक है) पर अपनी आंखें खोलना शुरू करते हैं, तो आपको पता चलेगा कि सादगी का आपका प्रभाव गलत है:) –

उत्तर

7

हाँ, आप तीन विकल्प यदि आप एक पूंछ सूचक के साथ एक अकेले लिंक्ड-सूची लिखना चाहते हैं:

  • सुरक्षित और परिवर्त्य: NodePtr उपयोग = Option<Rc<RefCell<Node<T>>>>
  • सुरक्षित और अपरिवर्तनीय: उपयोग NodePtr = Option<Rc<Node<T>>>
  • असुरक्षित और परिवर्त्य: उपयोग tail: *mut Node<T>

*mut अधिक कुशल होने जा रहा है, और यह Rc की तरह नहीं है वास्तव में को पूरी तरह बकवास राज्यों (जैसा कि आपने सही ढंग से घटाया है) का उत्पादन करने से रोक दिया है। यह सिर्फ यह गारंटी देने जा रहा है कि वे segfaults का कारण नहीं बनते हैं (और RefCell के साथ यह अभी भी रनटाइम क्रैश का कारण बन सकता है ...)।

आखिरकार, वेनिला सिंगल-लिंक्ड की तुलना में किसी भी लिंक्ड सूची में अधिक जटिल एक स्वामित्व की कहानी है जो जंग की स्वामित्व प्रणाली को सुरक्षित रूप से और कुशलता से एन्कोड करने के लिए बहुत जटिल है (यह एक पेड़ नहीं है)। मैं व्यक्तिगत रूप से उस बिंदु पर असुरक्षितता को स्वीकार करने और एक टुकड़े में फिनिश लाइन तक पहुंचने के लिए इकाई परीक्षणों पर झुकाव का पक्ष लेता हूं (एक उप-डेटा डेटा संरचना क्यों लिखें ...?)।

+0

यह निश्चित रूप से एक प्रमुख प्रश्न की तरह लग जाएगा, लेकिन मैं आपको आश्वासन देता हूं कि मैं वास्तव में जंग की भावना को समझने की कोशिश कर रहा हूं। यदि मुझे गैर-तुच्छ, गैर-पेड़ डेटा संरचनाओं को लिखने के लिए "असुरक्षितता को गले लगाने" की आवश्यकता है, तो मैं सी ++ के साथ क्यों नहीं रहूंगा, जहां मेरे पास पहले से ही कई वर्षों का अनुभव है? क्या यह निहितार्थ है कि सबसे अच्छी डेटा संरचनाएं पेड़ होनी चाहिए? या क्या कहानी का कोई और हिस्सा है कि मुझे याद आ रही है? – GrandOpener

+6

मैं तर्क दूंगा कि लेखन संग्रह कुछ नहीं है * अधिकांश कार्यक्रम * करने से परेशान होंगे। उन्हें पूर्व-निर्मित (शायद सिर्फ std से) डेटा संरचनाएं मिलेंगी। संग्रह मूल रूप से निम्न स्तर के निर्माण भी हैं। आपको सीधे सिस्टम आवंटक से बात करने की ज़रूरत है, आंशिक रूप से प्रारंभिक डेटा के साथ काम करें, और जटिल आविष्कार बनाए रखें। विशेष रूप से यदि आप प्रदर्शन चाहते हैं। एक बार जब आप अपना संग्रह बना लेते हैं, तो इसे पूरी तरह से सुरक्षित इंटरफ़ेस का खुलासा करना चाहिए, और किसी को भी अंदरूनी चीज़ों की परवाह करने की आवश्यकता नहीं है। जंग भी मौलिक पुस्तकालयों पर एक बड़ा बोझ डालता है। आवेदन सुरक्षा से एक बड़ी जीत मिलती है। –

+4

चूंकि सबसे अच्छी डेटा संरचनाएं पेड़ हैं: नहीं, सबसे अच्छी डेटा संरचनाएं सरणी हैं। :) –

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