Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

rust - Why does this read input before printing?

I'm having some problems with some basic I/O stuff. Specifically, the text "Please enter your name" is written to the output after I type in my name and hit Enter:

use std::io;

fn main() {
    print!("Please enter your name: ");

    let mut name = String::new();
    match io::stdin().read_line(&mut name) {
        Ok(_) => println!(""),
        Err(err) => println!("Could not parse input: {}", err)
    }

    println!("Hello, {}!", name.trim());
}

gives the following output:

Compiling chat v0.1.0 (file:///home/marcus/dev/rust/chat)
  Running `target/debug/chat`
marcus
Please enter your name: 
Hello, marcus!

Where the first "marcus" was entered by me. Why won't the program print "Please enter your name" before waiting for input?


Is it possible to "do nothing" if a returned Result is Ok? In the example, Ok() means that I have saved the input in the variable name. That's great. But what do I do with Ok() => in this case?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Why won't the program print "Please enter your name" before waiting for input?

Well, it did. It's just that, for performance reasons, standard output is buffered. The write completed, but it was only writing to memory. If you want it to actually display to the user, you have to trigger a flush. This can be done either by writing a newline, or by doing it explicitly:

io::Write::flush(&mut io::stdout()).expect("flush failed!");

// If you "use" `io::Write`...
io::stdout().flush().expect("flush failed!");

Also, is it possible to "do nothing" if a returned Result is Ok?

Sure. Just... do nothing.

match io::stdin().read_line(&mut name) {
    Ok(_) => { /* nothing */ },
    Err(err) => println!("Could not parse input: {}", err)
}    

The relevant requirement here is that all arms in a match have to have the same result type. In the case of println!, it results in a (); aside from an empty block (or another function that returns ()), you can just use a literal:

match io::stdin().read_line(&mut name) {
    Ok(_) => (),
    Err(err) => println!("Could not parse input: {}", err)
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...