Getting Started with Rust
After watching a lot of Rusty videos, and doing Hello World in Rust, I finally started a real project: Comparing Files.
While learning .Net, I wrote a program to search for duplicate files on the file system, including a Graphical User Interface. It worked pretty well.
Later, wile learning Scala, I wrote some code to find duplicate files on my computer, but I never got around to implementing a GUI. This was done after completing the Functional Programming Principles in Scala from Coursera. Naturally, the code was all based on functional programming with non-mutable data structures, and the end result was very satisfying, although the code was very hard to read. Most notably, I could convert the code to parallel by changing one line of code, adding the ".par" method in a critical place.
However, one aspect of the code, I programmed in Java, to make it more portable, the code to compare the equality of two files. After a lot of experimentation, I found that using Memory Mapped Files, my code ran four times faster for large files than the Apache standard library, but there a lot of tricks to getting Java to behave.
Rust
I started to implement the same basic services in Rust, and I have been delightfully surprised.
Code
use std::fs::File;
use std::io::Read;
trait Equal {
fn equal(&self, other: &Self) -> bool;
}
impl Equal for usize {
fn equal(&self, other: &Self) -> bool {
self == other
}
}
/// # Compare two files by their content
///
/// Do this efficiently by comparing the file size first, then the content. There are still some
/// efficiency improvements that can be made, but this is a good start.
///
/// TODO Diagnostics are none, just a boolean result.
impl Equal for str {
fn equal(&self, other: &Self) -> bool {
match File::open(self) {
Ok(mut file1) => match File::open(other) {
Ok(mut file2) => {
match file1.metadata() {
Ok(metadata1) => {
match file2.metadata() {
Ok(metadata2) => if metadata1.len() == metadata2.len() {
let mut buffer1 = Vec::with_capacity(metadata1.len() as usize);
let mut buffer2 = Vec::with_capacity(metadata2.len() as usize);
match file1.read_to_end(&mut buffer1) {
Ok(_) => {
match file2.read_to_end(&mut buffer2) {
Ok(_) => buffer1 == buffer2,
Err(_) => false
}
}
Err(_) => false
}
} else {
false
}
Err(_) => false
}
}
Err(_) => false
}
}
Err(_) => false,
}
Err(_) => false,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = Equal::equal(&2, &2);
assert_eq!(result, true);
let result = Equal::equal("Cargo.toml", "Cargo.toml");
assert_eq!(result, true);
}
}
Yes, this code looks like an ugly duckling for now because it has no diagnostics, it returns true or false, where any errors just return false. But, it was unbelievably easy to get the code to this point, a Walking Skeleton as a Proof of Concept, that is easy to work with.
领英推荐
Next Steps
Conclusions
The more I learn Rust, the more I play with it, the more impressed I am.
I really don't like the look of Rust code, too many short names and chicken track characters, looks too much like C and C++. But, I am willing to overlook that for now while I am trying to grok Rust.
What I can say for sure is: if your company, your enterprise, is not learning Rust, all of your competition will have a compelling advantage over you.
AI/ML Contractor - Machine Learning, Data Science, ML Pipeline Architecture
11 个月I'm still flummoxed. It's C with safety? Not Scala or exciting. Is it just very in-demand?