Rev() on an iterating element

I'm new to rust. trying solve some simple problems and ran into something.

use std::io;
use std::cmp::Ordering;

fn main(){
    let mut in1=String::new();
    io::stdin()
        .read_line(&mut in1).unwrap();                      //a number specifying he number of elements in the input eg 6
    let in1:i32=in1.trim().parse().unwrap();
    let in1 = in1/2;
    let mut in2= String::new();
    io::stdin()
        .read_line(&mut in2).unwrap();                      //input of an array in the format number number number etc. rg : 233 456 665 8239 361 0912
    let mut i=1;
    let mut fwd=String::new();
    for element in in2.split(' '){
        fwd.push_str(
            match i.cmp(&in1){
                // Ordering::Greater=>&element.rev()[..1],  //supposed to be the least significant digit of the number 
                Ordering::Greater=>
                    &element[..1],
                _ =>
                    &element[..1],                          //most significant digit of the number
            }

        );
        i+=1;
    }
    println!("{}",fwd);
    /* ^^ number having most significant digits of the first half of the input and least significant digits of the second half
            by the example this number should be 246912*/ 

}

when i tried to rev() on the iterating element i'm getting this error

error[E0599]: the method `rev` exists for reference `&str`, but its trait bounds were not satisfied
  --> src\main.rs:19:45
   |
19 |                 Ordering::Greater=>&element.rev()[..1],
   |                                             ^^^ method cannot be called on `&str` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `&str: Iterator`
           which is required by `&mut &str: Iterator`
           `str: Iterator`
           which is required by `&mut str: Iterator`

For more information about this error, try `rustc --explain E0599`.

i tried to figure it out but idk why it's not working so please help

You're not iterating element, you're indexing into it. To get just the last character, you could:

...or a variety of other approaches. Note that in my playgrounds, I'm also doing this:

    for element in in2.trim().split(' ') {
    //                 ^^^^^^

So that newlines don't interfere.


There are a lot of opportunities to panic here (unwrapping IO calls and iterator method results, indexing into Strings, and so on). As you learn more Rust, consider how you can handle such cases more gracefully. For the sort of online problems you're probably practicing with, it rarely matters (they tend to never give you unexpected inputs), but in real projects it definitely does.

1 Like

thanks you so much.
for some reason i thought reversing would be faster than finding the length and subtracting 1 which i now realize was stupid. can you tell me why rev() doesn't work on that string slice though ? it's really bugging me

For why rev() doesn't work on a string slice, consider the signature of Iterator::rev():

pub trait Iterator {
    fn rev(self) -> Rev<Self>
    where
        Self: Sized + DoubleEndedIterator;
}

The method rev() is defined on all sized types that implement DoubleEndedIterator. However, a string slice (&str) does not implement DoubleEndedIterator. Instead, the str type has methods that create a DoubleEndedIterator from a string slice. For instance,

The string slice itself has no rev() method, since there's no single way to look at it as a sequence of elements. Instead, it lets you specify what kind of iterator to reverse: if you have a string slice s, the iterators s.bytes().rev(), s.chars().rev(), s.split("...").rev() are all different ways to reverse its contents, and any of them can be valid depending on the situtation. In your case, you only need the chars() iterator, since you're splitting the string into single characters. But different programs often need to view string slices in some other way, and these methods give them the ability to do so.

4 Likes