Обращение строки в Rust

Что не так:

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

Я получаю сообщение об ошибке:

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

Каков правильный способ сделать это?

Ответ 1

Первая и самая фундаментальная проблема заключается в том, что вы не обращаете вспять строку Юникода. Вы меняете порядок кодовых точек, где вы хотите изменить порядок графем. Могут быть другие проблемы с этим, о которых я не знаю. Текст сложный.

Вторая проблема указана компилятором: вы пытаетесь сравнить строковый литерал с итератором char. chars и rev не генерируют новые строки, они генерируют ленивые последовательности, как с итераторами в целом. Следующие работы:

/*!
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()
        // 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 был в стандартной библиотеке как нестабильный метод, поэтому вышеприведенное будет нарушено с достаточно старыми версиями Rust. В этом случае вам нужно использовать UnicodeSegmentation::graphemes(s, true) вместо этого.

Ответ 2

Так как, как @DK. предположил, .graphemes() не доступен на &str в стабильном состоянии, вы можете просто сделать то, что @huon предложили в комментариях:

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