2014-06-11 9 views
179

मैं थोड़ी देर के लिए जंग से दूर रहा हूं और एक नया प्रकार String दिखाई दिया। इस और str के बीच अंतर क्या हैं? str के बजाय String का उपयोग कब करता है और इसके विपरीत? उनमें से एक को बहिष्कृत किया जा रहा है?जंग के 'स्ट्रिंग' और 'str` के बीच अंतर क्या हैं?

उत्तर

212

String गतिशील ढेर स्ट्रिंग प्रकार है, जैसे Vec: जब आप अपने स्ट्रिंग डेटा को स्वामित्व या संशोधित करने की आवश्यकता होती है तो इसका उपयोग करें।

str एक अपरिवर्तनीय स्मृति में कहीं गतिशील लंबाई के यूटीएफ -8 बाइट्स का अनुक्रम है। चूंकि आकार अज्ञात है, इसलिए कोई इसे केवल पॉइंटर के पीछे संभाल सकता है, जिसका अर्थ है कि str सबसे अधिक &str के रूप में प्रकट होता है: कुछ यूटीएफ -8 डेटा का संदर्भ, जिसे आमतौर पर "स्ट्रिंग स्लाइस" या सिर्फ "स्लाइस" कहा जाता है। एक टुकड़ा कुछ डेटा पर सिर्फ एक दृश्य है, और वह डेटा कहीं भी हो सकता है, उदा।

  • स्थिर भंडारण में: एक स्ट्रिंग शाब्दिक "foo"&'static str है। डेटा निष्पादन योग्य में हार्डकोड किया जाता है और जब प्रोग्राम चलता है तो स्मृति में लोड किया जाता है।
  • String: के डेटा के आवंटित एक ढेर के अंदर।
  • स्टैक पर: उदा। निम्नलिखित एक ढेर-आवंटित बाइट सरणी बनाता है, और उसके बाद हो जाता है एक view of that data as a &str:

    use std::str; 
    
    let x: &[u8] = &[b'a', b'b', b'c']; 
    let stack_str: &str = str::from_utf8(x).unwrap(); 
    

सारांश में, String उपयोग करें यदि आप स्ट्रिंग डेटा (अन्य कार्यों के लिए तार गुजर रहा है, या उन्हें क्रम में निर्माण की तरह स्वामित्व की जरूरत है), और &str का उपयोग करें यदि आपको केवल स्ट्रिंग के दृश्य की आवश्यकता है।

यह एक वेक्टर Vec<T> और एक टुकड़ा &[T] के बीच के रिश्ते के समान है, और के बीच के रिश्ते के समान है दर-मूल्य T और दर-संदर्भ सामान्य प्रकार के लिए &T


एक str निश्चित लंबाई है; आप अंत से परे बाइट्स नहीं लिख सकते हैं, या अमान्य बाइट पीछे पीछे छोड़ सकते हैं। चूंकि यूटीएफ -8 एक परिवर्तनीय चौड़ाई एन्कोडिंग है, इसलिए यह प्रभावी रूप से अपरिवर्तनीय होने के लिए सभी str एस को मजबूर करता है। आम तौर पर, उत्परिवर्तन के पहले की तुलना में अधिक या कम बाइट लिखने की आवश्यकता होती है (उदाहरण के लिए a (1 बाइट) को ä (2+ बाइट्स) के साथ str में अधिक कमरे बनाने की आवश्यकता होगी)।

पल यह केवल&str के रूप में प्रकट कर सकते हैं, लेकिन dynamically sized types अनुमति दे सकता है संदर्भ का एक दृश्य के लिए Rc<str> तरह बातें गिना UTF-8 बाइट्स। यह भी हो सकता है, str पूरी तरह से डीएसटी योजना में फिट नहीं है, क्योंकि कोई निश्चित आकार संस्करण (अभी तक) नहीं है।

+4

"अनुक्रम: निम्नलिखित कोड String कामयाब स्मृति में शाब्दिक स्ट्रिंग प्रतिलिपि करने की आवश्यकता बाइट्स (अज्ञात लंबाई ** **) "- क्या यह पुराना है? [डॉक्स] (https://doc.rust-lang.org/nightly/std/primitive.str.html) कहते हैं "ए 'और str' दो घटकों से बना है: कुछ बाइट्स और एक लंबाई के लिए एक सूचक। " – mrec

+3

यह पुराना नहीं है (वह प्रतिनिधित्व काफी स्थिर रहा है), बस थोड़ा अपमान: यह स्थिर रूप से ज्ञात नहीं है, कहें, '[u8; एन] '। – huon

+1

@mrec संकलन समय पर अज्ञात है, इसके आकार के बारे में धारणाएं नहीं बनाई जा सकती हैं, उदाहरण के लिए, एक स्टैक फ्रेम बनाते समय। इस प्रकार इसे अक्सर संदर्भ के रूप में क्यों माना जाता है, जिसका संदर्भ संकलन समय पर एक ज्ञात आकार है, जो एक सूचक का आकार है। – Sekhat

27

str, केवल &str के रूप में उपयोग किया जाता है, एक स्ट्रिंग स्लाइस है, जो यूटीएफ -8 बाइट सरणी का संदर्भ है।

String~str, जो एक बढ़ने योग्य, स्वामित्व वाली यूटीएफ -8 बाइट सरणी था, का उपयोग किया जाता था।

22

मैं एक सी है ++ पृष्ठभूमि है और मैं इसे बहुत उपयोगी के बारे में String और सी ++ मामले में &str सोचने के लिए मिला:

  • एक जंग String एक std::string की तरह है; यह स्मृति का मालिक है और स्मृति प्रबंधन के गंदे काम करता है।
  • ए जंग &strchar* (लेकिन थोड़ी अधिक परिष्कृत) की तरह है; यह हमें एक खंड की शुरुआत के लिए इंगित करता है उसी तरह से आप std::string की सामग्री के लिए सूचक प्राप्त कर सकते हैं।

क्या उनमें से कोई गायब होने जा रहा है? मुझे ऐसा नहीं लगता है। वे दो उद्देश्यों की सेवा करते हैं:

String बफर रखता है और उपयोग करने के लिए बहुत व्यावहारिक है। &str हल्का वजन है और स्ट्रिंग में "देखने" के लिए उपयोग किया जाना चाहिए। आप नई मेमोरी आवंटित किए बिना भागों को खोज, विभाजित, पार्स और यहां तक ​​कि प्रतिस्थापित भी कर सकते हैं।

&strString के अंदर देख सकता है क्योंकि यह कुछ स्ट्रिंग अक्षर को इंगित कर सकता है। (केवल हालांकि पढ़)

let a: String = "hello rust".into(); 

निम्नलिखित कोड आप शाब्दिक खुद का उपयोग प्रतिलिपि के बिना की सुविधा देता है UTF-8 के

let a: &str = "hello rust"; 
+0

एक string_view की तरह? –

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