signal-2024-02-01-19-47-41-855

  • @[email protected]
    link
    fedilink
    45
    edit-2
    10 months ago

    The collect’s in the middle aren’t necessary, neither is splitting by ": ". Here’s a simpler version

    fn main() {
        let text = "seeds: 79 14 55 13\nwhatever";
        let seeds: Vec<_> = text
            .lines()
            .next()
            .unwrap()
            .split_whitespace()
            .skip(1)
            .map(|x| x.parse::().unwrap())
            .collect();
        println!("seeds: {:?}", seeds);
    }
    

    It is simpler to bang out a [int(num) for num in text.splitlines()[0].split(' ')[1:]] in Python, but that just shows the happy path with no error handling, and does a bunch of allocations that the Rust version doesn’t. You can also get slightly fancier in the Rust version by collecting into a Result for more succinct error handling if you’d like.

    EDIT: Here’s also a version using anyhow for error handling, and the aforementioned Result collecting:

    use anyhow::{anyhow, Result};
    
    fn main() -> Result<()> {
        let text = "seeds: 79 14 55 13\nwhatever";
        let seeds: Vec = text
            .lines()
            .next()
            .ok_or(anyhow!("No first line!"))?
            .split_whitespace()
            .skip(1)
            .map(str::parse)
            .collect::>()?;
        println!("seeds: {:?}", seeds);
        Ok(())
    }
    
    • @[email protected]OP
      link
      fedilink
      English
      610 months ago

      Yeah I was trying to do something like reading the first line by getting an iterator and just looping through the other lines normally, since first line was kind of a special case but it got messy quick. I realized halfway that my collects were redundant but couldn’t really simplify it. Thanks

    • lad
      link
      fedilink
      2
      edit-2
      10 months ago

      Also, anyhow::Context provides a convenient way to turn Option and Result> into anyhow::Result

      Like this:

      use anyhow::Context;
      
      // to my understanding it's better to 
      // specify the types when their names 
      // are the same as in prelude to improve
      // readability and reduce name clashing
      fn main() -> anyhow::Result<()> {
          let text = "seeds: 79 14 55 13\nwhatever";
          let seeds: Vec = text
              .lines()
              .next()
              .context("No first line!")?     // This line has changed
              .split_whitespace()
              .skip(1)
              .map(str::parse)
              .collect::>()?;
          println!("seeds: {:?}", seeds);
          Ok(())
      }
      

      Edit: line breaks

  • @Schmeckinger
    link
    1810 months ago

    You can’t really blame that on rust.

      • @[email protected]
        link
        fedilink
        610 months ago

        Rust borrows a lot of it’s design from functional programming languages like Haskell, which has its good and bad. You could also choose to implement this behavior iteratively like typical C programs, but that tends to be ugly in other ways.

        Personally, I’ve grown fond of the functional style. You see it in other places too, like the higher order functions in JavaScript. What’s good about them in Rust is you still get amazing performance due to zero-cost abstraction. Trying to implement it yourself would likely be slower, so use them any chance you get.

  • @GeniusIsme
    link
    210 months ago

    Show the alternative, I’ll have a good laugh.

          • @[email protected]
            link
            fedilink
            English
            1
            edit-2
            10 months ago

            Python style iterator comprehension

            (wonder if someone has made that into a macro. if no one has I will)

            • @[email protected]
              link
              fedilink
              110 months ago

              I don’t think it would be readable. Too much going on. You’d need an outer iter over lines, an inner over words, a check for number and a conversion. And there would be zero error handling.

              • @[email protected]
                link
                fedilink
                English
                210 months ago

                No less readable than half the Python comprehensions I’ve written.

                zero error handling.

                Not necessarily. The macro could look for a ? at the end of the final expression (the bit that comes first in a comprehension) and return a Result.