何时在Rust中使用as_* vs to_* vs into_*?

13

根据标准库示例,我的理解是:

当函数完全吸收所有权并输出另一种类型时,使用into_约定,例如into_iter()。这个理解正确吗?

真正令人困惑的是as_to_之间的区别。
似乎to_owned()中的to_接受一个类型的引用并输出一个新的相关类型(像类型强制转换),而to_string()接受一个类型的引用并输出一个新类型(例如类型转换)。

但是,as_as_ptr中也似乎起到了类型强制转换的作用。除了as_ptras_mut之外,我找不到其他任何例子。

有人能否解释一下我们需要使用特定命名约定的确切情况,并举一个超出标准库使用范围的现实示例?


10
Rust API准则 - 命名本文介绍Rust编程语言中API的命名规范,其中涵盖了标识符、类型、函数、常量等方面的命名原则。提出了一些具体的建议和指导,如避免缩写、使用动词开头的函数名等。此外,还介绍了针对“as_”、“to_”、“into_”等特殊情况下的转换方法的一般约定。建议在实现类型转换时,优先使用“as_”、“to_”、“into_”等前缀,而不是“from_”。这些准则可以帮助开发者编写易于理解、明确且一致的API,并促进代码的可读性和可维护性。 - kmdreko
to_ownedto_string 不是类型强制转换。它们通常等同于 clone,会深度复制所涉及的对象,或者分配内存。 - PitaJ
@PitaJ 我同意,但是在 to_owned 的情况下,to_ 听起来像类型强制转换,实际上并不是。这就是混淆的地方。API指南表帮了很大的忙。 - manikawnth
感谢@kmdreko。这个链接应该是文档的一部分。非常有帮助。 - manikawnth
1个回答

13

Rust API准则的命名部分包括“转换”方法的建议,并显示了一个方便的表:

前缀代价所有权
as_免费借用 -> 借用
to_昂贵借用 -> 借用
借用 -> 拥有(非Copy类型)
拥有 -> 拥有(Copy类型)
into_可变拥有 -> 拥有(非Copy类型)

该指南继续提供例如str::as_bytes(), str::to_lowercase(), String::into_bytes()等示例,以及一些关于抽象和可变性的其他考虑。

更快的理解方式:

  • 如果消耗数据,请使用into_*
  • 如果返回数据的另一个“视图”,请使用as_*
  • 否则,请使用to_*

这些规则基本上都被标准库和大多数生态系统创建包所遵循。尽管如此,这些更多地是指导方针而不是实际规则。惯例有帮助,但不需要严格遵守。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,