Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does rust's read_line function use a mutable reference instead of a return value?

Tags:

rust

Consider this code to read the user input in rust

use std::io;
fn main() {
    let mut input = String::new();
    io::stdin()
        .read_line(&mut input)
        .expect("error: unable to read user input");
    println!("{}", input);
}

why is there no way to do it like this?

use std::io;
fn main() {
    let mut input = io::stdin()
        .read_line()
        .expect("error: unable to read user input");
    println!("{}", input);
}

it would be more convenient to other languages

like image 390
Kingsly2407 Avatar asked Aug 28 '20 04:08

Kingsly2407


People also ask

What is a mutable reference in Rust?

Back to Rust. A mutable reference is a borrow to any type mut T , allowing mutation of T through that reference. The below code illustrates the example of a mutable variable and then mutating its value through a mutable reference ref_i .

What is a reference in Rust?

A reference represents a borrow of some owned value. You can get one by using the & or &mut operators on a value, or by using a ref or ref mut pattern. For those familiar with pointers, a reference is just a pointer that is assumed to not be null.

How to get the value of a referent in rust?

And to get the value of the referent, you'd use the * operator: All the values and references created above were immutable, which is the default in Rust. If you want to change the value through a reference, create a mutable reference.

What is mutable reference in rust?

Rust supports mutable references which means we can change the value it references if it’s a mutable variable. There are some restrictions on how we use mutable references. You can have only one mutable reference to a particular value in a particular scope to prevent data races

What is the 'mutable references' lesson?

The "Mutable References" Lesson is part of the full, The Rust Programming Language course featured in this preview video. Here's what you'd learn in this lesson:

Is it possible to use rust pointers in C++?

C++ pointers (even smart pointers) can't match Rust references' safety. References in C++, in contrast, are quite dissimilar to Rust references, even syntactically. Creating and dereferencing a reference is implicit in C++:


1 Answers

TL;DR The closest you have is lines(), and the reason read_line works like it does is efficiency. The version that uses lines() looks like this:

use std::io::{self, BufRead};

fn main() {
    // get next line from stdin and print it
    let input = io::stdin().lock().lines().next().unwrap().expect("IO error");
    println!("{}", input);
}

In general, read_line() is not designed for use in small interactive programs; there are better ways to implement those.

The read_line method comes from the generic io::BufRead trait, and its primary use is reading input, typically redirected from files or other programs, and possibly coming in large quantities. When processing large amounts of data, it is advantageous to minimize the number of allocations performed, which is why read_line is designed to reuse an existing string. A typical pattern would be:

let mut line = String::new();
while input.read_line(&mut line)? != 0 {
    // do something with line
    ...
    line.clear();
}

The number of (re-)allocations is kept minimal, as line will grow only as needed to accommodate the input lines. Once a typical size is reached, allocations will become very rare, and once the largest line is read, they will disappear altogether. If read_line() supported the "convenient" interface, then the above loop would indeed look nicer - for example:

while let Some(line) = read_new_line(some_input)? {
    // process the line
    ...
}

...but would require a new allocation and deallocation for each line. In throw-away or learning programs this can be perfectly fine, but BufRead is intended as a building block for efficient IO, so its read_line method favors performance over convenience.

like image 59
user4815162342 Avatar answered Oct 06 '22 13:10

user4815162342