ऐसा क्यों होता है?
चलो इसे तोड़ दो, लाइन-बाय-लाइन
let s1 = "foobar";
हमने एक शाब्दिक स्ट्रिंग बनाया है जो UTF-8 में एन्कोडेड है । UTF-8 हमें यूनिकोड के 1,114,112 कोड पॉइंट्स को इस तरह से एनकोड करने की अनुमति देता है, जो कि बहुत कॉम्पैक्ट है यदि आप दुनिया के किसी ऐसे क्षेत्र से आते हैं, जो ज्यादातर ASCII में पाए जाने वाले वर्णों में टाइप करते हैं , 1963 में बनाया गया एक मानक। UTF-8 एक चर लंबाई है एन्कोडिंग, जिसका अर्थ है कि एक एकल कोड बिंदु 1 से 4 बाइट्स तक हो सकता है । छोटे एनकोडिंग ASCII के लिए आरक्षित हैं, लेकिन कई कांजी UTF-8 में 3 बाइट लेते हैं ।
let mut v: Vec<char> = s1.chars().collect();
यह char
अभिनेताओं का एक वेक्टर बनाता है । एक चरित्र एक 32-बिट संख्या है जो सीधे एक कोड बिंदु पर मैप करता है। यदि हमने ASCII- केवल पाठ के साथ शुरुआत की है, तो हमने अपनी मेमोरी आवश्यकताओं को चौगुना कर दिया है। यदि हमारे पास सूक्ष्म विमान से वर्णों का एक समूह था , तो शायद हमने उसका अधिक उपयोग नहीं किया है।
v[0] = v[0].to_uppercase().nth(0).unwrap();
यह पहले कोड बिंदु को पकड़ता है और अनुरोध करता है कि इसे अपरकेस वैरिएंट में बदला जाए। दुर्भाग्य से हममें से जो अंग्रेजी बोलते हुए बड़े हुए हैं, वहां हमेशा "छोटे अक्षर" से "बड़े अक्षर" की मैपिंग एक-से-एक नहीं होती है । साइड नोट: हम उन्हें ऊपरी और निचले मामले कहते हैं, क्योंकि पत्रों का एक बॉक्स दिन में वापस पत्र के दूसरे बॉक्स के ऊपर था ।
जब कोड बिंदु के पास कोई अपरकेस संस्करण नहीं होगा तो यह कोड घबरा जाएगा। मुझे यकीन नहीं है कि अगर वे मौजूद हैं, तो वास्तव में। यह तब भी शब्दार्थ में विफल हो सकता है जब एक कोड बिंदु में एक अपरकेस वैरिएंट होता है जिसमें कई अक्षर होते हैं, जैसे कि जर्मन ß
। ध्यान दें कि, वास्तव में कभी भी वास्तविक दुनिया में पूंजीकृत नहीं किया जा सकता है, यह केवल एक उदाहरण है जिसे मैं हमेशा याद रख सकता हूं और खोज सकता हूं। 2017/06/29 के रूप में, वास्तव में, जर्मन वर्तनी की आधिकारिक नियम तो अपडेट किए गए हों दोनों "ẞ" और "एसएस" वैध पूंजीकरण हैं !
let s2: String = v.into_iter().collect();
यहां हम वर्णों को वापस UTF-8 में परिवर्तित करते हैं और उन्हें स्टोर करने के लिए एक नए आवंटन की आवश्यकता होती है, क्योंकि मूल चर को निरंतर मेमोरी में संग्रहीत किया जाता था ताकि रन टाइम पर मेमोरी न खींची जा सके।
let s3 = &s2;
और अब हम इसका संदर्भ लेते हैं String
।
यह एक साधारण समस्या है
दुर्भाग्य से यह सच नहीं है। शायद हमें दुनिया को स्कॉर्पियो में बदलने का प्रयास करना चाहिए ?
मुझे लगता है कि char::to_uppercase
पहले से ही ठीक से यूनिकोड संभालता है।
हां, मैं निश्चित रूप से उम्मीद करता हूं। दुर्भाग्य से, यूनिकोड सभी मामलों में पर्याप्त नहीं है। के लिए धन्यवाद ओर इशारा करते हुए के लिए huon तुर्की मैं , जहां दोनों ऊपरी ( İ ) और लोअर केस ( मैं ) संस्करणों में एक बिंदु है। यही कारण है कि कोई नहीं है, है एक पत्र के समुचित पूंजीकरण i
; यह स्रोत पाठ के स्थान पर भी निर्भर करता है ।
सभी डेटा प्रकार रूपांतरणों की आवश्यकता क्यों है?
क्योंकि आप जिस डेटा प्रकार के साथ काम कर रहे हैं वह महत्वपूर्ण है जब आप शुद्धता और प्रदर्शन के बारे में चिंतित हैं। A char
32-बिट्स है और एक स्ट्रिंग UTF-8 एनकोडेड है। वे अलग चीजें हैं।
अनुक्रमण बहु-बाइट, यूनिकोड वर्ण लौटा सकता है
यहां कुछ बेमेल शब्दावली हो सकती है। एक char
है एक मल्टी-बाइट यूनिकोड वर्ण।
टुकड़ा करने की क्रिया एक स्ट्रिंग यदि संभव हो तो आप बाइट-दर-बाइट जाते हैं, लेकिन यदि आप अक्षर सीमा पर नहीं हैं मानक पुस्तकालय आतंक जाएगा।
एक चरित्र प्राप्त करने के लिए एक स्ट्रिंग को अनुक्रमित करने के कारणों में से एक को कभी भी लागू नहीं किया गया था, क्योंकि बहुत से लोग ASIIII वर्णों के सरणियों के रूप में तारों का दुरुपयोग करते हैं। एक चरित्र को सेट करने के लिए एक स्ट्रिंग को अनुक्रमणित करना कभी भी कुशल नहीं हो सकता है - आपको 1-4 बाइट्स को एक मूल्य के साथ बदलने में सक्षम होना होगा जो कि 1-4 बाइट्स भी है, जिससे बाकी स्ट्रिंग काफी उछाल लेती है।
to_uppercase
एक ऊपरी मामले के चरित्र को वापस कर सकता है
जैसा कि ऊपर उल्लेख किया गया है, ß
एक एकल वर्ण है, जब पूंजीकृत होता है, दो वर्ण बन जाता है ।
समाधान
ट्रेंटक्ल का जवाब भी देखें जो केवल ASCII वर्णों को अपरकेस करता है।
मूल
अगर मुझे कोड लिखना था, तो यह ऐसा लगेगा:
fn some_kind_of_uppercase_first_letter(s: &str) -> String {
let mut c = s.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().chain(c).collect(),
}
}
fn main() {
println!("{}", some_kind_of_uppercase_first_letter("joe"));
println!("{}", some_kind_of_uppercase_first_letter("jill"));
println!("{}", some_kind_of_uppercase_first_letter("von Hagen"));
println!("{}", some_kind_of_uppercase_first_letter("ß"));
}
लेकिन मैं शायद crates.io पर अपरकेस या यूनिकोड की खोज करूंगा और किसी को मुझसे ज्यादा स्मार्ट बनाने के लिए इसे संभालने दूंगा।
उन्नत
"मुझसे ज्यादा होशियार किसी व्यक्ति" की बात करते हुए, वेद्रेक बताते हैं कि संभवत: पहला कैपिटल कोडपाइंट एक्सेस होने के बाद पुनरावृत्त को एक स्लाइस में बदलना अधिक कुशल है। यह memcpy
बाइट्स के बाकी हिस्सों के लिए अनुमति देता है ।
fn some_kind_of_uppercase_first_letter(s: &str) -> String {
let mut c = s.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
}
}
ß
जर्मन के रूप में व्याख्या करने पर कैपिटलाइज़ करें । संकेत: यह एक एकल चरित्र नहीं है। यहां तक कि समस्या कथन जटिल हो सकता है। उदाहरण के लिए, उपनाम के पहले चरित्र को भुनाना अनुचित होगाvon Hagen
। यह एक वैश्विक दुनिया में रहने का एक पहलू है, जिसमें विभिन्न प्रथाओं के साथ हजारों वर्षों की विभिन्न संस्कृतियां हैं और हम उन सभी को 8 बिट्स और कोड की 2 पंक्तियों में स्क्वैश करने की कोशिश कर रहे हैं।