2015-01-17 28 views
5
में एक स्ट्रिंग पीछे

इसमें क्या गलत है:जंग

error[E0369]: binary operation `==` cannot be applied to type `std::iter::Rev<std::str::Chars<'_>>` 
--> src/main.rs:4:5 
    | 
4 |  assert_eq!(word.chars().rev(), "skwol"); 
    |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    | 
    = note: an implementation of `std::cmp::PartialEq` might be missing for `std::iter::Rev<std::str::Chars<'_>>` 
    = note: this error originates in a macro outside of the current crate 

ऐसा करने का सही तरीका क्या है:

fn main() { 
    let word: &str = "lowks"; 
    assert_eq!(word.chars().rev(), "skwol"); 
} 

मैं इस तरह एक त्रुटि प्राप्त?

उत्तर

12

पहला, और सबसे मौलिक, समस्या यह है कि यह एक यूनिकोड स्ट्रिंग को उलट नहीं करता है। आप कोड पॉइंट्स के ऑर्डर को उलट रहे हैं, जहां आप ग्रैफेम्स के ऑर्डर को रिवर्स करना चाहते हैं। इसके साथ अन्य मुद्दे भी हो सकते हैं जिनके बारे में मुझे जानकारी नहीं है। पाठ कठिन है।

दूसरा मुद्दा संकलक द्वारा इंगित किया गया है: आप एक स्ट्रिंग अक्षर की तुलना char इटरेटर से करने की कोशिश कर रहे हैं। chars और rev नए तारों का उत्पादन नहीं करते हैं, वे आलसी अनुक्रमों का उत्पादन करते हैं, जैसे सामान्य रूप से इटरेटर्स के साथ। The following works:

/*! 
Add the following to your `Cargo.toml`: 

```cargo 
[dependencies] 
unicode-segmentation = "0.1.2" 
``` 
*/ 
extern crate unicode_segmentation; 
use unicode_segmentation::UnicodeSegmentation; 

fn main() { 
    let word: &str = "loẅks"; 
    let drow: String = word 
     // Split the string into an Iterator of &strs, where each element is an 
     // extended grapheme cluster. 
     .graphemes(true) 
     // Reverse the order of the grapheme iterator. 
     .rev() 
     // flat_map takes each element of an iterator, turns that element into 
     // a new iterator, then outputs the elements of these sub-iterators as 
     // one long chain. In this case, we're turning each grapheme cluster 
     // into an Iterator of code points, then yielding all those code points. 
     // That is, this is now an Iterator of chars from the reversed grapheme 
     // clusters. 
     .flat_map(|g| g.chars()) 
     // Collect all the chars into a new owned String. 
     .collect(); 

    assert_eq!(drow, "skẅol"); 

    // Print it out to be sure. 
    println!("drow = `{}`", drow); 
} 

ध्यान दें कि graphemes, इसलिए ऊपर जंग के लिए पर्याप्त रूप से पुराने संस्करणों के साथ टूट जाएगा एक अस्थिर विधि के रूप में मानक पुस्तकालय में हुआ करता था। उस स्थिति में, आपको इसके बजाय UnicodeSegmentation::graphemes(s, true) का उपयोग करने की आवश्यकता है।

+6

' स्ट्रिंग 'लागू 'सेटरेटर <&str>'। इसके अलावा, मुझे लगता है कि * वास्तविक * सबसे मौलिक समस्या सामान्य रूप से इटरेटर्स, तारों और प्रकारों को गलत समझ रही है (समझने योग्य, कई भाषाएं इतनी "pedantic" नहीं हैं), यूनिकोड शुद्धता के कुछ हद तक बेहतर बिंदु नहीं हैं। – huon

+0

@dbaupp: मैं एक समस्या का तर्क दूंगा जो कार्यान्वयन भाषा से स्वतंत्र है * एक * से अधिक मौलिक है जो किसी विशेष भाषा के लिए विशिष्ट है। : डी लेकिन यह जानना अच्छा लगता है कि 'स्ट्रिंग'' सेटरेटर <&str> 'का समर्थन करता है। थोड़ी दयालुता यह भंडारण को पूर्व-आवंटित नहीं करती है, लेकिन आप जो भी चाहते हैं उसे हमेशा प्राप्त नहीं कर सकते ... –

+0

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

10

चूंकि @ डीके के रूप में। । का सुझाव दिया, .graphemes() स्थिर में &str पर उपलब्ध नहीं है, तो आप के रूप में अच्छी सिर्फ तुम क्या सुझाव दिया @huon कर सकता टिप्पणी में: मुझे लगता है कि आप कर सकते हैं बस `.rev() इकट्ठा()` के बाद से,

fn main() { 
    let foo = "palimpsest"; 
    println!("{}", foo.chars().rev().collect::<String>()); 
}