blog podcast

Turbofish

It’s been quite a while, but as part of solving the Advent of Code problems I’ve once again started digging into Rust. I can still remember from before that it can be tough in the beginning, but after a while there’s an intuition that starts building up. For me I wanted to start with something quite basic, I’m working on solving problem 8 in advent of code.

First part is separating the problem into smaller problems to solve, and here the first problem is of course to parse the input that you’ll be working with. I have strings of numbers that I want to covert into numbers. My first take was to use arrays for these numbers. It turns out though that Rust wants to know how big your arrays are going to be. I suppose that makes sense because a) it let’s your compiler verify that you don’t have any monkey business going on with starting to iterate outside of the array, and b) it makes it a lot easier to allocate what needs to be copied. Although there is only one problem input to work with, which means I could theoretically have known the size of this array I want to keep my solution dynamic enough to work on any well formatted problem input. So I dropped the arrays to use Vec instead which allows me to have dynamic sized arrays.

Next part of the problem was to convert numbers inside my string into actual numbers. The code ended up looking like this:

pub fn parse_row(row: &str) -> Vec<u8>  {
    let result: vec<u8> = row.chars().map(|c| c.to_digit(10).unwrap() as u8).collect::<vec<u8>>();
    result
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_parse_row() {
        let row = "123456789";
        let parsed_row = parse_row(row);
        assert_eq!(parsed_row, vec![1, 2, 3, 4, 5, 6, 7, 8, 9]);
    }
}

So what’s happening here? First we turn the string into an iterable list of Chars. We then map these Chars one by one by calling to_digit. What’s the unwrap about? That’s error handling. to_digit returns Result, and could also contain a failure. By calling unwrap I simply forfeit my error handling logic saying I should create a Panic if something is wrong. Then we call collect which turns my iterable into a Vector. And here comes the Turbofish. The compiler is not able to know what kind of vector I’m collecting. To me it seems it should be able to understand from the cast that it should be a vector of type u8. I still don’t understand why, but some day I’ll hopefully meet someone that can explain it to me.