प्रश्न का पहला भाग शायद बहुत आम है और पर्याप्त कोड नमूने हैं जो बताते हैं कि अल्फान्यूमेरिक्स की यादृच्छिक स्ट्रिंग कैसे उत्पन्न करें। मेरे द्वारा उपयोग किया जाने वाला कोड यहां।
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
fn main() {
let rand_string: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.collect();
println!("{}", rand_string);
}
कोड का यह टुकड़ा हालांकि संकलित नहीं करता है, (नोट: मैं रात में हूं):
error[E0277]: a value of type `String` cannot be built from an iterator over elements of type `u8`
--> src/main.rs:8:10
|
8 | .collect();
| ^^^^^^^ value of type `String` cannot be built from `std::iter::Iterator<Item=u8>`
|
= help: the trait `FromIterator<u8>` is not implemented for `String`
ठीक है, उत्पन्न होने वाले तत्व u8
प्रकार के हैं। तो मुझे लगता है कि यह एक सरणी या वेक्टर है u8
:
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
fn main() {
let r = thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.collect::<Vec<_>>();
let s = String::from_utf8_lossy(&r);
println!("{}", s);
}
और यह संकलित और काम करता है!
2dCsTqoNUR1f0EzRV60IiuHlaM4TfK
सब ठीक है, सिवाय इसके कि मैं पूछना चाहता हूं कि क्या कोई बता सकता है कि वास्तव में प्रकारों के बारे में क्या होता है और इसे कैसे अनुकूलित किया जा सकता है।
प्रश्न
.sample_iter(&Alphanumeric)
u8
का उत्पादन करता है औरchar
s का नहीं?- मैं दूसरे चर
s
से कैसे बच सकता हूं और सीधेu8
को utf-8 वर्ण के रूप में व्याख्या कर सकता हूं? मुझे लगता है कि स्मृति में प्रतिनिधित्व बिल्कुल नहीं बदलेगा? - इन तारों की लंबाई हमेशा 30 होनी चाहिए। मैं
Vec
दूर के ढेर आवंटन को कैसे अनुकूलित कर सकता हूं? इसके अलावा वे वास्तव मेंString
के बजायchar[]
हो सकते हैं।
2 जवाब
.sample_iter(&Alphanumeric)
u8 उत्पन्न करता है न कि वर्ण?
हां, इसे रैंड v0.8.1 में बदल दिया गया था। आप 0.7.3 के लिए डॉक्स में देख सकते हैं :
impl Distribution<char> for Alphanumeric
लेकिन फिर 0.8.0 के लिए डॉक्स में:
impl Distribution<u8> for Alphanumeric
मैं दूसरे चर
s
से कैसे बच सकता हूं और सीधेu8
को utf-8 वर्ण के रूप में व्याख्या कर सकता हूं? मुझे लगता है कि स्मृति में प्रतिनिधित्व बिल्कुल नहीं बदलेगा?
ऐसा करने के कुछ तरीके हैं, सबसे स्पष्ट है कि प्रत्येक u8
को एक char
में डाला जाए:
let s: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.map(|x| x as char)
.collect();
या, From<u8>
इंस्टेंस का इस्तेमाल करके char
का:
let s: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.map(char::from)
.collect();
बेशक यहां, चूंकि आप जानते हैं कि प्रत्येक u8
मान्य UTF-8 होना चाहिए, आप String::from_utf8_unchecked
, जो from_utf8_lossy
से तेज है (हालांकि शायद as char
मेथड के समान स्पीड के आसपास):
let s = unsafe {
String::from_utf8_unchecked(
thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.collect::<Vec<_>>(),
)
};
अगर, किसी कारण से, unsafe
आपको परेशान करता है और आप सुरक्षित रहना चाहते हैं, तो आप धीमे String::from_utf8
और unwrap
Result
ताकि आपको UB के बजाय घबराहट हो (भले ही कोड चाहिए कभी भी घबराएं या यूबी):
let s = String::from_utf8(
thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.collect::<Vec<_>>(),
).unwrap();
इन तारों की लंबाई हमेशा 30 होनी चाहिए। मैं
Vec
दूर के ढेर आवंटन को कैसे अनुकूलित कर सकता हूं? इसके अलावा वे वास्तव में स्ट्रिंग्स के बजायchar[]
हो सकते हैं।
सबसे पहले, मेरा विश्वास करो, आप वर्णों के सरणी नहीं चाहते हैं। उनके साथ काम करने में मजा नहीं आता। यदि आप एक स्टैक स्ट्रिंग चाहते हैं, तो एक u8
सरणी है, फिर std::str::from_utf8
या तेज़ std::str::from_utf8_unchecked
(फिर से केवल प्रयोग करने योग्य क्योंकि आप जानते हैं कि मान्य utf8 जनरेट किया जाएगा।)
ढेर आवंटन को अनुकूलित करने के लिए, यह उत्तर देखें। मूल रूप से, यह कुछ हैकनेस/कुरूपता के साथ संभव नहीं है (जैसे कि अपना स्वयं का फ़ंक्शन बनाना जो एक इटरेटर को 30 तत्वों की सरणी में एकत्र करता है)।
एक बार कॉन्स्ट जेनरिक के स्थिर हो जाने के बाद, एक बहुत सुंदर समाधान।
{a href="https://docs.rs/rand/0.8.0/rand/distributions/struct.Alphanumeric.html#example" rel="nofollow noreferrer">दस्तावेज़ में पहला उदाहरण के लिए rand::distributions::Alphanumeric
दर्शाता है कि यदि आप u8
s को char
s में बदलना चाहते हैं, तो आपको char::from
फ़ंक्शन का उपयोग करके उन्हें map
करना चाहिए:
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
fn main() {
let rand_string: String = thread_rng()
.sample_iter(&Alphanumeric)
.map(char::from) // map added here
.take(30)
.collect();
println!("{}", rand_string);
}
संबंधित सवाल
नए सवाल
string
एक स्ट्रिंग प्रतीकों का एक परिमित अनुक्रम है, आमतौर पर पाठ के लिए उपयोग किया जाता है, हालांकि कभी-कभी मनमाने डेटा के लिए।