Rust 的设计者有没有公开说过为什么索引数组的语法与索引元组的语法不同?

在 Rust 中,元组可以使用点索引(例如:x.0),而数组可以使用方括号索引(例如:x[0])。乍一看,这在我看来似乎会使重构现有代码变得更加困难,而没有任何实际目的。但是,我可能只是错过了一些东西。 Rust 的创建者是否曾对此发表评论并告诉我们他们为什么选择以这种方式构建语言?

lyxxzrb 回答:Rust 的设计者有没有公开说过为什么索引数组的语法与索引元组的语法不同?

此元组字段访问语法是在 RFC 184 (discussion thread) 中引入的。在此之前,您必须解构所有元组(和元组结构)以访问它们的值,或使用标准库中的特殊特征。

RFC 本身没有详细介绍替代的 [index] 语法,但讨论线程确实有。我认为我们最终采用 .index 语法的三个主要原因:

[]std::ops::Index

相关

[index] 语法与 ops::Index 特征密切相关。它允许您为自己的类型重载该运算符。按照 trait 的设计方式,index 方法(在您使用 [] 时调用)必须每次都返回相同的类型。所以 ops::Index 不能用于异构类型。并且由于 [] 与 trait 非常相关,因此 [] 的一些特殊用法可能会很奇怪,但不使用 std::ops::Index

正如在 reddit 上所指出的,索引本身(即 tuple[0]tuple[1] 等)作为替代方案没有意义,因为元组是异构的。 (绝对不能让它们实现 Index* 特征。)

——Comment

索引语法 [is] 实际上非常不合适。值得注意的是,其他地方的索引语法都具有一致的类型,但元组是异构的,因此 a[0]a[1] 将具有不同的类型。

——Comment

元组/元组结构作为具有匿名字段的结构

Rust 有其他异构数据类型:structs。您可以使用 .field 语法访问它们的字段。将元组结构描述为具有未命名字段的结构,并将元组描述为未命名的元组结构,将两者都视为结构是有意义的。然后,.0 就像引用了一个未命名的字段。

我觉得,尤其是在静态类型语言中,a[1],a[2],...,a[N] 的类型应该是一样的。

是的,这就是为什么没有人提倡向元组添加索引语法的原因。 tuple.1 语法更适合;它基本上是匿名字段访问,而不是索引。

——Comment

元组和元组结构只是具有按其定义排序的匿名字段的结构,因此两者都应支持将字段作为左值直接访问的语法,以使使用它们更一致和更容易。

——Comment

受 Swift 的影响

Swift 已经有了这种语法,并且似乎受到了影响:

作为参考,Swift 允许使用这种元组索引语法,并允许使用它进行赋值。

——Comment

+1 swift 有很多实用的调整,IMO 就是其中之一。

——Comment

感谢 swift,将会有一个熟悉 .0 .1 ... 符号的大型社区

——Comment


顺便说一句:从这个帖子可以看出,“Rust 的设计者”实际上在大多数情况下只是社区成员。当然,当时 RFC 流程存在问题(而且仍然不完美),但您可以在线阅读大部分讨论,社区成员对提议的语法发表评论。

,

我没有看到任何明确提及该决定背后的推理,但考虑到索引语法的原始含义,这是有道理的。追溯到 C,数组是连续的,这意味着它们存储数据,这样数据的每个字节都从前一个字节开始。当您访问数组的第 N 个元素时,您实际上是在访问距数组开头 N * sizeof(type) 个字节的数据。

---------------------
| 0 | 1 | 2 | 3 | 4 |
---------------------

此方法仅在数组中的每个值都是相同类型并因此使用相同数量的内存时才有效,就像 Rust arraysslices 的情况,但不一定如此tuple 类型。如果设计者允许访问带有索引的元组数据,那么可能会导致那些学习 Rust 的人对元组的使用做出错误的假设。

元组通常用于制作简单的“数据类”,它只存储数据,不需要任何关联的方法。因此,您应该将元组视为一个结构体,其中所有字段都是公开的并通过数字访问。

本文链接:https://www.f2er.com/1338.html

大家都在问