How to use a method in Rust without the "use" keyword?

Viewed 253

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.

0 Answers
Related