Rust 的设计者是否曾经公开说过为什么索引数组的语法与索引元组的语法不同?
Did the Designers of Rust ever publicly say why the syntax of indexing an array is different to indexing a tuple?
在 Rust 中,元组可以使用点进行索引(例如:x.0
),而数组可以使用方括号进行索引(例如:x[0]
)。乍一看,这似乎会让重构现有代码变得更加困难,而没有任何实际目的。但是,我可能只是遗漏了一些东西。 Rust 的创造者是否曾对此发表评论并告诉我们他们为什么选择以这种方式构建语言?
我没有看到任何明确提及该决定背后的原因,但考虑到索引语法的原始含义,这是有道理的。追溯到 C,数组是连续的,这意味着它们存储数据时每个字节的数据都从前一个字节开始。当您访问数组的第 N 个元素时,您实际上是在访问距数组开头 N * sizeof(type)
字节的数据。
---------------------
| 0 | 1 | 2 | 3 | 4 |
---------------------
此方法仅在数组中的每个值都是相同类型并因此使用相同数量的内存时才有效,就像 Rust arrays
and slices
but not necessarily so with the tuple
类型的情况一样。如果设计者允许访问带有索引的元组数据,可能会导致那些学习 Rust 的人对元组的使用做出错误的假设。
元组一般用于制作简单的“数据类”,只存储数据,不需要任何关联方法。因此,您应该将元组视为一个结构,其中所有字段都是 public 并按数字访问。
此元组字段访问语法是在 RFC 184 (discussion thread) 中引入的。在此之前,您必须解构所有元组(和元组结构)才能访问它们的值,或者使用标准库中的特殊特征。
RFC 本身并没有详细介绍替代 [index]
语法,但讨论线程进行了详细介绍。我看到我们最终使用 .index
语法的三个主要原因:
[]
与 std::ops::Index
有关
[index]
语法与 ops::Index
特性密切相关。它允许您为自己的类型重载该运算符。特征的设计方式,index
方法(当您使用 []
时调用)每次都必须 return 相同的类型。所以 ops::Index
不能用于异构类型。由于 []
与特征密切相关,所以 []
的一些特殊用法可能很奇怪,但不使用 std::ops::Index
.
As also pointed out on reddit, indexing as such (i.e. tuple[0]
, tuple[1]
etc.) wouldn't make sense as an alternative, because tuples are heterogenous. (They definitely couldn't be made to implement the Index*
traits.)
Indexing syntax [is] actually a really bad fit. Notably, indexing syntax everywhere else has a consistent type, but a tuple is heterogenous so a[0]
and a[1]
would have different types.
Tuples/tuple 结构作为具有匿名字段的结构
Rust 有其他异构数据类型:struct
s。您可以使用 .field
语法访问它们的字段。并且将元组结构描述为具有未命名字段的结构,并将元组描述为未命名的元组结构,将两者有点像结构一样对待是有意义的。然后,.0
感觉就像在引用一个未命名的字段。
I feel, especially in statically-typed languages, the types of a[1], a[2], ..., a[N] should be the same.
是的,这就是为什么没有人提倡向元组添加索引语法的原因。 tuple.1 语法更合适;它基本上是匿名字段访问,而不是索引。
Tuples and tuple structs are just structs with anonymous fields ordered by their definition, so both should support syntax for accessing a field as an lvalue directly to make working with them more consistent and easier.
受到Swift
的影响
Swift 已经有了这种语法并且似乎产生了影响:
For reference, Swift allows this tuple indexing syntax, and allows for assignment with it.
+1 swift has a lot of nice pragmatic tweaks, and this is one of them, IMO.
thanks to swift there's going to be a large community familiar with the .0 .1 ... notation
顺便说一句:从这个帖子可以看出,“Rust 的设计者”在大多数情况下确实只是社区成员。当然,当时的 RFC 过程有它的问题(而且它仍然不完美),但你可以在线阅读大部分讨论,社区成员对提议的语法发表评论。
在 Rust 中,元组可以使用点进行索引(例如:x.0
),而数组可以使用方括号进行索引(例如:x[0]
)。乍一看,这似乎会让重构现有代码变得更加困难,而没有任何实际目的。但是,我可能只是遗漏了一些东西。 Rust 的创造者是否曾对此发表评论并告诉我们他们为什么选择以这种方式构建语言?
我没有看到任何明确提及该决定背后的原因,但考虑到索引语法的原始含义,这是有道理的。追溯到 C,数组是连续的,这意味着它们存储数据时每个字节的数据都从前一个字节开始。当您访问数组的第 N 个元素时,您实际上是在访问距数组开头 N * sizeof(type)
字节的数据。
---------------------
| 0 | 1 | 2 | 3 | 4 |
---------------------
此方法仅在数组中的每个值都是相同类型并因此使用相同数量的内存时才有效,就像 Rust arrays
and slices
but not necessarily so with the tuple
类型的情况一样。如果设计者允许访问带有索引的元组数据,可能会导致那些学习 Rust 的人对元组的使用做出错误的假设。
元组一般用于制作简单的“数据类”,只存储数据,不需要任何关联方法。因此,您应该将元组视为一个结构,其中所有字段都是 public 并按数字访问。
此元组字段访问语法是在 RFC 184 (discussion thread) 中引入的。在此之前,您必须解构所有元组(和元组结构)才能访问它们的值,或者使用标准库中的特殊特征。
RFC 本身并没有详细介绍替代 [index]
语法,但讨论线程进行了详细介绍。我看到我们最终使用 .index
语法的三个主要原因:
[]
与 std::ops::Index
有关
[index]
语法与 ops::Index
特性密切相关。它允许您为自己的类型重载该运算符。特征的设计方式,index
方法(当您使用 []
时调用)每次都必须 return 相同的类型。所以 ops::Index
不能用于异构类型。由于 []
与特征密切相关,所以 []
的一些特殊用法可能很奇怪,但不使用 std::ops::Index
.
As also pointed out on reddit, indexing as such (i.e.
tuple[0]
,tuple[1]
etc.) wouldn't make sense as an alternative, because tuples are heterogenous. (They definitely couldn't be made to implement theIndex*
traits.)
Indexing syntax [is] actually a really bad fit. Notably, indexing syntax everywhere else has a consistent type, but a tuple is heterogenous so
a[0]
anda[1]
would have different types.
Tuples/tuple 结构作为具有匿名字段的结构
Rust 有其他异构数据类型:struct
s。您可以使用 .field
语法访问它们的字段。并且将元组结构描述为具有未命名字段的结构,并将元组描述为未命名的元组结构,将两者有点像结构一样对待是有意义的。然后,.0
感觉就像在引用一个未命名的字段。
I feel, especially in statically-typed languages, the types of a[1], a[2], ..., a[N] should be the same.
是的,这就是为什么没有人提倡向元组添加索引语法的原因。 tuple.1 语法更合适;它基本上是匿名字段访问,而不是索引。
Tuples and tuple structs are just structs with anonymous fields ordered by their definition, so both should support syntax for accessing a field as an lvalue directly to make working with them more consistent and easier.
受到Swift
的影响Swift 已经有了这种语法并且似乎产生了影响:
For reference, Swift allows this tuple indexing syntax, and allows for assignment with it.
+1 swift has a lot of nice pragmatic tweaks, and this is one of them, IMO.
thanks to swift there's going to be a large community familiar with the .0 .1 ... notation
顺便说一句:从这个帖子可以看出,“Rust 的设计者”在大多数情况下确实只是社区成员。当然,当时的 RFC 过程有它的问题(而且它仍然不完美),但你可以在线阅读大部分讨论,社区成员对提议的语法发表评论。