Counter type (signature) - std::iter::from_fn

How to make the signature of the “counter” variable explicit?
I am trying to understand what type is the “counter”?

fn main() {
   let mut count = 0;
   let counter = std::iter::from_fn(move || {
       // Increment our count. This is why we started at zero.
       count += 1;


       // Check to see if we've finished counting or not.
       if count < 6 {
           Some(count)
       } else {
           None
       }
   });
   assert_eq!(counter.collect::<Vec<_>>(), &[1, 2, 3, 4, 5]);
}

This works fine - it is possible to make the signature explicit for variable "str_arr" :

fn main() {
   let str_arr: [String; 3] = core::array::from_fn(|_| "bb".to_string());
   println!("{:?}", str_arr); // ["bb", "bb", "bb"]
}

similar question: How to spell a signature for iter().chain()?

Answer - it is a closure:
https://doc.rust-lang.org/reference/types/closure.html

A closure expression - produces a closure value with a unique, anonymous type that cannot be written out.

2 Likes

counter there isn't a closure in itself. The type returned by std::iter::from_fn is FromFn<F>, where F is the anonymous closure type that you pass in. The FromFn type wraps the closure and makes it an Iterator.

4 Likes

One way to determine the type of the value of an expression is to use let temp: () = expression;. As long as the value of expression is not the unit type, the compiler will emit an error message of the form expected (), found [type]. In this case, the compiler would emit an error like expected (), found FromFn<{closure@main.rs:5:37}>, which @jameseb7 mentioned is the FromFn struct which takes an anonymous closure type as a generic parameter.

2 Likes

If you wish you could name the type - e.g. to make a field with the type - your options so far are

  • coerce to a function pointer if possible
    • (your OP captures state so it's not possible)
  • dyn type erasure
    • e.g. Box<dyn Iterator<Item=i32>>
  • use generics yourself, like FromFn

(The plan is to have ways to create a nameable alias to types like these eventually.)

1 Like