I am learning Rust coming from a Java background. In Java, I would commonly import java.util.ArrayList;
. As far as I understand, this was a convenience to prevent needing to put java.util.
preceding every occurrence of ArrayList
.
Consider the following Rust:
use std::io;
use std::io::Write;
fn main() {
print!("Hello World!");
// Let's flush the Buffer
io::stdout().flush().expect("Oh No!");
}
If the first use
is removed, io
is no longer specified. We can fix this by adding std::
before io
.
The program now reads like this:
use std::io::Write;
fn main() {
print!("Hello World!");
// Let's flush the Buffer
std::io::stdout().flush().expect("Oh No!");
}
What catches my interest is the second use
- It is required to use the flush
method on stdout. This makes my Java analogy very unhappy - I expect flush
to be a part of the "stdout
thing", and if I have the thing I can use the methods - but that is clearly not the case here.
Is it possible to write the above program without the second use
? If so, what is the syntax to fully specify flush
?
What is going on?
Solution
Solved by some helpful comments below. The linked questions, while not the same question, do have similar answers.
The line in question:
std::io::stdout().flush().expect("Oh no!");
In my experience, stdout.flush()
implies that flush
is a function within stdout. In Java, stdout would be an object, passed to flush "behind-the-scenes" as this
. In Python, it would be explicitly in the method signature as self
.
In Rust, in this situation, stdout
is being passed to flush
via dot notation. To fully specify flush
, stdout
must be passed in the "traditional" way, within flush
's parenthesis.
In short, Object.method()
is equivalent to method(Object)
. (At least here - I am still learning, and may be very wrong.)
To fully specify both stdout
and flush
, I use the following:
std::io::Write::flush(&mut std::io::stdout()).expect("Oh no!");
Looking further, the first argument to expect
is "self", furthering the x.y() == y(x)
idea. Translating the above into y(x) format completely, we arrive at the very complicated:
std::result::Result::expect(
std::io::Write::flush(
&mut std::io::stdout()
),
"Oh no!"
);
This has been enlightening. Thank you all, and I hope this helps someone in the future.