【问题标题】:What makes `impl Trait` as an argument "universal" and as a return value "existential"?是什么让 `impl Trait` 作为参数“通用”和返回值“存在”?
【发布时间】:2018-06-04 10:01:50
【问题描述】:

我在阅读RFC on "expanding" impl Trait 时发现以下内容:

相比之下,首先学习:fn take_iter(t: impl Iterator),然后尝试:fn give_iter() -> impl Iterator 的程序员将是 成功,没有任何严格的理解,他们只是 从普遍性转变为存在性。

虽然我从逻辑的角度理解普遍与存在,但是是什么让第一个高于普遍而第二个存在?

【问题讨论】:

  • 之所以选择这种方式是因为这些是最常见的用例。在某些情况下,存在参数类型或通用返回类型会很有用,但这些情况相对较少,因此 RFC 选择不实现它们并保持简单。
  • @interjay 一个普遍量化的返回类型的常见例子是Into::into()。调用者提供他们想要返回的类型(通常通过推理)。

标签: rust universal existential-type


【解决方案1】:

RFC 以多种方式多次定义术语:

存在类型(被调用者选择类型)和通用类型(调用者选择)之间

围绕universals vs.existentials(在今天的Rust中,泛型vs impl Trait)有很多讨论。

  • 通用量化,即“对于任何类型 T”,即“调用者 选择”。这就是今天泛型的工作方式。当你写 fn foo<T>(t: T),您是说该功能适用​​于任何 选择T,然后让您的呼叫者选择T

  • 存在量化,即“对于某些类型 T”,即“被调用者” 选择”。这就是 impl Trait 今天的工作方式(作为回报 仅位置)。当你写fn foo() -> impl Iterator时,你是 说该函数将产生某种类型的T 实现 Iterator,但不允许调用者假设任何其他内容 关于那种类型。

TL;DR:

  • fn take_iter(t: impl Iterator) — 调用 take_iter 的人选择具体类型。该函数必须适用于实现该特征的整个“宇宙”类型。

  • fn give_iter() -> impl Iteratorgive_iter 的实现选择具体类型。有一些类型“存在”并实现了函数返回的特征。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    相关资源
    最近更新 更多