Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing string in Rust

Tags:

rust

I want to compare a string input from stdin to a static string with no luck.

Here is what I have tried so far:

fn main() -> () {
    let mut line = "".to_string();
    let exit = "exit".to_string(); 

    while line.as_slice() != exit.as_slice() {
        let input = std::io::stdin().read_line().ok();

        line.push_str( input.unwrap().to_string().as_slice() );

        assert_eq!(line, exit);
    }   
}

However during assertion it failed. How should I compare a string input to a static string in Rust?

Your help is very much appreciated.

like image 660
Joshua Partogi Avatar asked Nov 29 '14 10:11

Joshua Partogi


People also ask

Can you compare strings in Rust?

One of the common operations on strings is comparison. We can use the eq(), eq_ignore_ascii_case() and == to compare strings in Rust.

Can I use == to compare two strings?

You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.

How do you compare 2 strings?

Using String. equals() :In Java, string equals() method compares the two given strings based on the data/content of the string. If all the contents of both the strings are same then it returns true. If any character does not match, then it returns false.

What are the 3 ways to compare two string objects?

There are three ways to compare String in Java: By Using equals() Method. By Using == Operator. By compareTo() Method.


1 Answers

First of all, the line contains the line terminator. You probably want to use trim (or one of its variants) to ignore that.

Secondly, you're doing a lot of unnecessary conversions and allocations. Try to avoid those.

Third, to_string is (or at least, was the last time I checked) inefficient due to over-allocation. You want into_string.

Fourth, the quickest way to go from a String to a &str is to "cross-borrow" it; given a String s, &*s will re-borrow it as a &str. This is because a String implements Deref<&str>; in other words, String acts kind of like a smart pointer to a borrowed string, allowing it to decay into a simpler form.

Fifth, unless you're doing something unusual, you can rewrite this as a for loop using the lines iterator method.

Sixth, be aware that stdin() actually allocates a new buffered reader every time you call it. Not only that, but characters read into the buffer do not get "pushed back" into STDIN when a new buffer is created; that data is simply lost. So you really don't want to be calling it in a loop. If you need to, call it once and keep the result in a variable.

So, I end up with this:

fn main() {
    for line in std::io::stdin().lines() {
        // Extract the line, or handle the error.
        let line = match line {
            Ok(line) => line,
            Err(err) => panic!("failed to read line: {}", err)
        };

        assert_eq!(line.trim(), "exit");
    }
}
like image 79
DK. Avatar answered Oct 14 '22 03:10

DK.