1

I'm having trouble reversing a string in the newest version of rust, I saw this post but I'm still getting some errors. I'm trying to reverse a string and compare the two without any luck:

fn is_palindromic(num: int) -> bool {
    let num_str = num.to_str();
    let rev_num_str = num_str.chars_rev().collect();
    if rev_num_str == num_str {
        return true;
    }else{
        return false;
    }

}

then I receive the error:

main.rs:8:28: 8:39 error: type `collections::string::String` does not implement
any method in scope named `chars_rev`
main.rs:8       let rev_num_str = num_str.chars_rev();
Community
  • 1
  • 1
Syntactic Fructose
  • 18,936
  • 23
  • 91
  • 177
  • 3
    BTW, you don't need to allocate a whole new `String` to compare: you can use [`std::iter::order::equals`](http://doc.rust-lang.org/master/std/iter/order/fn.equals.html) to compare two iterators directly: `equals(num_str.as_slice().chars(), num_str.as_slice().chars().rev())`. (Also, I have a feeling you're not using 0.10 if you have the `String` type defined, are you using master/a nightly?) – huon Jun 09 '14 at 03:16

1 Answers1

5

Many of the traditionally useful string methods are defined in the std::str::StrSlice trait. To get a slice from a String value, you can call the as_slice method. It looks like chars_rev is no longer defined in the StrSlice trait, but there is a chars method which returns an iterator Chars.

This particular iterator implements the DoubleEndedIterator trait, which means it can be reversed by calling rev. That should be all you need:

fn is_palindromic(num: int) -> bool {
    let num_str = num.to_str();
    let rev_num_str: String = num_str.as_slice().chars().rev().collect();
    return rev_num_str == num_str;
}

fn main() {
    println!("{}", is_palindromic(12321));
}

Note that I also added a type annotation to rev_num_str since the compiler can't infer its concrete type (collect is polymorphic and can build many different kinds of "container" values). You could alternatively instantiate collect specifically:

let rev_num_str = num_str.as_slice().chars().rev().collect::<String>();
BurntSushi5
  • 13,917
  • 7
  • 52
  • 45
  • thanks! What is the use of `collect()` in these cases though? – Syntactic Fructose Jun 09 '14 at 03:59
  • It consumes an iterator into a container. In this case, the container is a `String`. But you could also use `Vec` to get a vector of characters instead of a string. Remember that the `rev` method returns an iterator, so it has to be consumed in some way to check for equality. (@dbaupp's suggestion will avoid the allocation of a new container like `String`.) – BurntSushi5 Jun 09 '14 at 04:48
  • I guess this is a good first approximation. For completeness one should probably normalize the string so that graphemes are represented using a single code point (if possible). Unicode is complex and I can't say I'm fully aware of all its intricacies. – sellibitze Jun 09 '14 at 20:31
  • 1
    @sellibitze, in this case, the string always consists of just `-0123456789`, I.e. there's no need to handle codepoints/normalisation/semantic reversing. In fact this could be implemented more efficiently using byte iterators. – huon Jun 10 '14 at 08:40