What makes `impl Trait` as an argument “universal” and as a return value “existential”?

后端 未结 1 693
鱼传尺愫
鱼传尺愫 2020-12-21 07:35

I was reading the RFC on \"expanding\" impl Trait when I came upon the following:

By contrast, a programmer who first learned: fn take_iter(t: i

相关标签:
1条回答
  • 2020-12-21 08:16

    The RFC defines the terms multiple times in multiple manners:

    between existential types (where the callee chooses the type) and universal types (where the caller chooses)

    There's been a lot of discussion around universals vs. existentials (in today's Rust, generics vs impl Trait).

    • Universal quantification, i.e. "for any type T", i.e. "caller chooses". This is how generics work today. When you write fn foo<T>(t: T), you're saying that the function will work for any choice of T, and leaving it to your caller to choose the T.

    • Existential quantification, i.e. "for some type T", i.e. "callee chooses". This is how impl Trait works today (which is in return position only). When you write fn foo() -> impl Iterator, you're saying that the function will produce some type T that implements Iterator, but the caller is not allowed to assume anything else about that type.

    TL;DR:

    • fn take_iter(t: impl Iterator) — the person calling take_iter picks the concrete type. The function has to work for the entire "universe" of types that implement the trait.

    • fn give_iter() -> impl Iterator — the implementation of give_iter picks the concrete type. There is some type which "exists" and implements the trait that will be returned by the function.

    0 讨论(0)
提交回复
热议问题