Rust

2015-01-17 14 views
5
bir dizeyi Ters bu nesi var

:Rust

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 

bu yapmanın doğru yolu nedir:

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

böyle bir hata alıyorum?

cevap

12

İlk ve en temel sorun, bir Unicode dizesini tersine çevirme şeklinizin bu olmamasıdır. grafemes sırasını tersine çevirmek istediğiniz kod noktalarının sırasını tersine çeviriyorsunuz. Bununla ilgili bilmediğim başka sorunlar olabilir. Metin zor.

İkinci sorun, derleyici tarafından belirtilmiştir: bir dize değişmezini char yineleyici ile karşılaştırmaya çalışıyorsunuz. chars ve rev, yeni dizeler üretmez, genel olarak yineleyicilerde olduğu gibi, tembel diziler üretir. The following works: Yukarıdaki Rust yeterli eski sürüm kırmak böylece graphemes, kararsız bir yöntem gibi standart kütüphane olarak kullanılan

/*! 
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); 
} 

not edin. Bu durumda, bunun yerine UnicodeSegmentation::graphemes(s, true)'u kullanmanız gerekir.

+6

O zamandan beri, sadece '.rev()') (toplayabilir düşünmek ' String, 'FromIterator <&str>' öğesini uygular. Ayrıca, fwiw, bence * gerçek * en temel problem, yineleyici yineleyiciler, dizeler ve genel olarak türler (anlaşılabilir, pek çok dil "akıcı" değil), bir şekilde daha küçük unicode doğruluğu noktaları değildir. – huon

+0

@dbaupp: Uygulama dilinden bağımsız bir problemin, * belirli bir dile özgü olandan daha temel olduğunu iddia ediyorum. : D Ama 'String' 'FromIterator <&str>' özelliğini desteklediğini bilmek güzel. Biraz yazık ki, depolama alanını önceden ayırmaz, ancak istediğiniz her şeyi elde edemezsiniz ... –

+0

Eh, soru belirli bir kod parçasının neden belirli bir dilde neden derlenmediğiyle ilgilidir. beklenmedik bir çıktı veriyor (yani algoritma ile dilden bağımsız bir problem), bu nedenle sorunun kendisi için temel sorun, Pas'a özgü tip hatalarıdır. Yine de, unicode'un zor olduğundan bahsetmek kesinlikle iyidir. – huon

10

@DK olarak. .graphemes() ahırda &str kullanılamaz, önerilen, siz de sadece Yorum önerilen @huon ne olabilir.

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