← All posts

Iterator vs IntoIterator & cfg

rust

Today I split my time between the iterators video and my CLI project.

I also refreshed the difference between Iterator and IntoIterator.

In yesterday’s journal I got a bit into the Iterator trait. Well, IntoIterator is a trait that implies that something can be converted into an Iterator.

For example, Vec<T> itself is not an iterator. But since it implements IntoIterator, it can be converted into an Iterator.

let v = vec![1, 2, 3];

let iter = v.into_iter();

assert_eq!(Some(1), iter.next());
assert_eq!(Some(2), iter.next());
assert_eq!(Some(3), iter.next());
assert_eq!(None, iter.next());

In the video, there’s also an interesting comparison between different kinds of loops:

fn main() {
  let vs = vec![1, 2, 3];

  for v in vs {
    // consumes vs, owned v
  }
  for v in vs.iter() {
    // borrows vs, & to v 
  }
  for v in &vs {
    // equivalent to vs.iter()
  }
}

Luckily, the compiler will help us to choose the correct one, but it is fundamental to know our fundamentals :)

Cfg

Today I also learned about cfg: https://doc.rust-lang.org/rust-by-example/attribute/cfg.html

This came by from working on my CLI project. I know from experience that it’s the best way to learn.

This CLI project I’m doing is a Pomodoro timer. I want to play a notification sound, so I’m using rodio.

There was a useful log message that appeared constantly. Checking the docs, there is a way to eliminate it. And I thought: how can I have it on my development but not in the released version?

And there was the answer: the cfg attribute and macro. With cfg, you can conditionally run code and booleans depending on many factors: https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute

I ended up doing:

sink_handle.log_on_drop(cfg!(debug_assertions));

Where cfg! is a macro that returns a boolean, and debug_assertions will differentiate between development and production: https://doc.rust-lang.org/reference/conditional-compilation.html#debug_assertions