Turbofish in rust

Consider the following code (or run it in rust playground here):

If you ran it in the playground linked above, you will see the following compiler error.

Because collect() is so general, it can cause problems with type inference. As such, collect() is one of the few times you’ll see the syntax affectionately known as the ‘turbofish’: ::<>. This helps the rust’s inference algorithm understand specifically which collection you’re trying to collect into.

In the above case, it is not clear if the collection is supposed to be a Vec, VecDeque, HashSet, HashMap or anything else that implements FromIterator.

There are two ways of fixing the above issue:
1st Way: By annotating doubled:

In both cases, the type annotation on doubled makes it clear what type of collection the collect() is going to collect into. The second option works because the rust’s compiler can infer exactly what type of Vec<_> collection it is going to be because iter returns u32. So compiler can exactly infer that the partial type hint _ in Vec<_> has to be Vec<u32>.

2nd Way: turbofish:

Like in 1st way, because collect() only cares about what you’re collecting into, you can still use a partial type hint, _, with the turbofish:

turbofish does not always work

There are times where you need to make type explicit via annotation. Turbofish won’t work. This has to do with history. Turbofish was created to deal with some corner cases in generics. If you apply on functions that don’t support generics, turbofish will not work.

Consider this code:

Obviously, this gives an error as compiler does not know to what type do we want to convert num to, So, let’s try turbofish.

No dice. We get a different error.

The only way to resolve this is via annotation in type space. (LHS is type space and RHS is expression space).
let number :i64 = num.into();

This inconsistency is bit confusing and not very obvious in the beginning. This is because the of the way generics are implemented in into() function signature vs collect().
Here is the function signature for into():

and here is the function signature for collect():

it is that <B> in collect that makes it possible to use turbofish. Since into does not have this syntax, it will not work here.

Turbofish has its share of haters as it makes generics syntax inconsistent in some cases. There is a whole reddit thread on this topic here and the attempt to remove turbofish from rust that ended in absolute dismal failure.




No Comments


You can leave the first : )



Leave a Reply

Your email address will not be published. Required fields are marked *