Loading posts...
Loading posts...
As a software engineer manily working with Python, I've recently been diving deeper into Rust, exploring how it handles common programming tasks that I usually breeze through in Python. Today, I want to share my experience building console applications in Rust, specifically focusing on user input handling and how it differs from Python's approach.
Those of you familiar with Python know how straightforward handling console input can be. A simple call to input()
and you're done:
name = input("what is your name? ")
print(f"Hello {name}!")
When I first approached the same task in Rust, I was struck by how much more explicit we need to be. Here's the equivalent code:
use std::io;
fn main() {
println!("What is your name?");
let mut input: String = String::new();
io::stdin()
.read_line(&mut input)
.expect("Failed to read line!");
println!("Hello {}!", input.trim());
}
At first glance, this might seem like unnecessary complexity. However, working with Rust has helped me appreciate why this verbosity exists. The explicit handling of mutable strings and error cases forces us to think about aspects of our program that Python abstracts away.
While I appreciate Rust's explicit approach, there's nothing wrong with creating our own abstractions once we understand what's happening under the hood. Here's a utility function I've been using that provides a more familiar interface while maintaining Rust's safety guarantees:
fn ask_question(question: &str) -> String {
println!("{question}");
let mut input: String = String::new();
io::stdin()
.read_line(&mut input)
.expect("Oops! Looks like there be a sea monster in the I/O waters.");
input.trim().to_string()
}
This gives us a more concise way to handle user input while still leveraging Rust's safety features. Here's how we can use it in a complete program:
use std::io;
fn ask_question(question: &str) -> String {
println!("{question}");
let mut input: String = String::new();
io::stdin()
.read_line(&mut input)
.expect("Oops! Looks like there be a sea monster in the I/O waters.");
input.trim().to_string()
}
fn main() {
println!("đ Welcome to the Rustic Adventure! đ");
let name = ask_question("What do they call ye, brave coder?");
let age = ask_question("How many orbits around the sun have ye completed?");
println!("đ Ahoy, {name}! Ready to set sail into the Rustic seas\nof coding at the youthful age of {age}? đąâ");
}
Coming from Python, Rust's approach to console I/O initially felt overly complex. However, this complexity serves a purpose. By making things explicit, Rust encourages us to think about:
While I still reach for Python when I need to quickly prototype something, I've grown to appreciate Rust's approach for systems where reliability and explicit error handling are crucial.
The next time you're building a console application in Rust, consider what level of abstraction makes sense for your use case. Sometimes, the verbose approach might be exactly what you need; other times, creating your own abstractions (like our ask_question
function) might make more sense.
Happy coding!
Ahmed