को वीइसी
Vec<&str>
को इस तरह से
Vec<String>
परिवर्तित कर सकते हैं:
let mut items = Vec::<&str>::new();
for item in &another_items {
items.push(item);
}
मैं कल्पना वहाँ बेहतर विकल्प हैं?
को वीइसी
Vec<&str>
को इस तरह से
Vec<String>
परिवर्तित कर सकते हैं:
let mut items = Vec::<&str>::new();
for item in &another_items {
items.push(item);
}
मैं कल्पना वहाँ बेहतर विकल्प हैं?
यह एक collect
उपयोग करता है:
let strs: Vec<&str> = another_items.iter().map(|s| s as &str).collect();
another_items.iter().map(|item| item.deref()).collect::<Vec<&str>>()
deref()
उपयोग करने के लिए आपके द्वारा उपयोग किए जोड़ना होगा use std::ops::Deref
वहाँ यह करने के लिए काफी कुछ तरीके, कुछ नुकसान कर रहे हैं, दूसरों को बस अधिक पठनीय हैं कुछ लोगों के लिए।
यह dereferences s
(प्रकार &String
की है) एक String
"दाहिने हाथ की ओर संदर्भ" है, जो फिर एक str
"दाहिने हाथ की ओर संदर्भ" के लिए Deref
विशेषता के माध्यम से dereferenced है और फिर एक &str
में वापस कर दिया है। यह ऐसा कुछ है जो आमतौर पर संकलक में देखा जाता है, और मैं इसे मूर्खतापूर्ण मानता हूं।
let v2: Vec<&str> = v.iter().map(|s| &**s).collect();
यहाँ Deref
विशेषता के deref
समारोह map
कार्य करने के लिए दिया जाता है। यह बहुत साफ है लेकिन विशेषता के use
की आवश्यकता है या पूरा पथ दे रहा है।
let v3: Vec<&str> = v.iter().map(std::ops::Deref::deref).collect();
यह हटाई गई है, यदि आप ऐसा नहीं करना चाहिए, क्योंकि यह |s| s: &str
(बलात्कार वाक्य रचना) के साथ भविष्य में किया जा सकता है।
let v4: Vec<&str> = v.iter().map(|s| s as &str).collect();
यह (पूरे String
में सिर्फ एक टुकड़ा) String
के RangeFull
टुकड़ा लेता है और यह करने के लिए एक संदर्भ लेता है। यह मेरी राय में बदसूरत है।
let v5: Vec<&str> = v.iter().map(|s| &s[..]).collect();
यह वह जगह है coercions का उपयोग करता है एक &str
में एक &String
कन्वर्ट करने के लिए। भविष्य में s: &str
अभिव्यक्ति द्वारा भी प्रतिस्थापित किया जा सकता है।
let v6: Vec<&str> = v.iter().map(|s| { let s: &str = s; s }).collect();
निम्नलिखित (धन्यवाद @ huon-dbaupp) AsRef
विशेषता है, जो पूरी तरह से अपने-अपने उधार प्रकार के स्वामित्व प्रकार से मैप करने के लिए मौजूद है उपयोग करता है। इसका उपयोग करने के दो तरीके हैं, और फिर, किसी भी संस्करण की सुंदरता पूरी तरह से व्यक्तिपरक है।
let v7: Vec<&str> = v.iter().map(|s| s.as_ref()).collect();
और
let v8: Vec<&str> = v.iter().map(AsRef::as_ref).collect();
मेरे लब्बोलुआब यह v8
समाधान का उपयोग के बाद से यह सबसे स्पष्ट रूप से व्यक्त करता है कि आप क्या चाहते है।
अन्य उत्तरों बस काम करते हैं।
fn my_func<T: AsRef<str>>(list: &[T]) { ... }
बजाय
:
मैं बस का कहना है कि यदि आप एकVec<&str>
में
Vec<String>
कन्वर्ट करने के लिए कोशिश कर रहे हैं केवल यह एक समारोह
Vec<&str>
तर्क के रूप में लेने के लिए पास करना चाहते हैं, के रूप में समारोह हस्ताक्षर संशोधन पर विचार
fn my_func(list: &Vec<&str>) { ... }
जैसा कि इस प्रश्न से इंगित किया गया है: Function taking both owned and non-owned string collections। इस तरह दोनों वैक्टर बस रूपांतरण की आवश्यकता के बिना काम करते हैं।
use std::iter::FromIterator;
let v = Vec::from_iter(v.iter().map(String::as_str));
ध्यान दें कि String::as_str
जंग 1.7 के बाद से स्थिर है:
यहाँ एक और विकल्प है।
स्पष्ट रूप से 'डेफ' (विशेष रूप से एक मुक्त फ़ंक्शन के रूप में) को कॉल करना काफी अजीब आईएमओ पढ़ता है, मुझे व्यक्तिगत रूप से 'v2' या 'v5' nicer मिलता है। (कोई भी 'as_ref', 'v.iter() का उपयोग कर सकता है। नक्शा (| s | s.as_ref()) ...' इस फ़ॉर्म के जेनेरिक रूपांतरणों के लिए सामान्य विधि है, उदाहरण के लिए 'std' में कई फ़ंक्शन 'पी: AsRef '।) –
huon
धन्यवाद, आप पूरी तरह से सही हैं। 'AsRef' यहां अधिक उपयुक्त है। मैंने पोस्ट अपडेट किया –