是否有任何技术原因Rust设计为元组使用点表示法而不是使用索引表示法(innodb_buffer_pool_size
)?
t[2]
点符号在访问struct和object的属性时似乎很自然。我无法在线找到资源或解释。
答案 0 :(得分:10)
我没有参与设计决策,但这是我的观点:
元组包含混合类型。也就是说,无法保证属性i
。
但是,传统的索引工作的前提是t[i]
中的t[i]
不必是编译时常量,这反过来意味着{{>> i
1}}需要对所有可能的pub trait Index<Idx> where Idx: ?Sized {
type Output: ?Sized;
fn index(&'a self, index: Idx) -> &'a Self::Output;
}
统一。在实现索引的所有其他生锈集合中都是如此。具体来说,通过实现Index特征,可以使锈类型成为可索引的,定义如下:
Self::Output
因此,如果您想要一个元组来实现索引,那么Self::Output
应该是什么类型的?解决此问题的唯一方法是使match t[i]
成为枚举,这意味着元素访问必须包含在程序员的无用21.650
子句(或类似的东西)上。并且,您将在运行时而不是编译时捕获类型错误。
此外,您现在必须实现边界检查,这又是一个运行时错误,除非您在元组实现中更聪明。
你可以通过要求索引按编译时常量来绕过这些问题,但是在那一点上,元组项访问假装表现得像普通的索引操作,而实际上表现不一致所有其他防锈容器,并没有什么好处。
答案 1 :(得分:8)
这个决定是在RFC 184中做出的。 动机部分包含详细信息:
现在访问元组和元组结构的字段非常痛苦 - 必须单独依靠模式匹配来提取值。这就成了一个问题,即在标准库
(core::tuple::Tuple*)
中创建了12个特征,以便更轻松地进行元组值访问,添加.valN()
,.refN()
和.mutN()
方法来帮助实现这一目标。但这不是一个非常好的解决方案 - 它要求在标准库中实现特征,而不是语言,以及在使用时导入的特征。总的来说这不是一个问题,因为大部分时间std::prelude::*
都是导入的,但这仍然是一个黑手党,并不能解决当前的问题。它也只支持长度达12的元组,这通常不是问题,但强调当前情况有多糟糕。
the associated pull request中的讨论也很有用。
答案 2 :(得分:4)
使用t.2
语法而不是t[2]
的原因最好在comment中说明:
索引语法在其他地方具有一致的类型,但元组是异质的,因此
a[0]
和a[1]
将具有不同的类型。
答案 3 :(得分:1)
我想提供一个使用函数式语言(Ocaml)的经验答案,因为我已经发布了这个问题。
除了@ rom1v引用之外,像a[0]
这样的索引语法在其他地方也被用于某种序列结构,其中元组不是。例如,在Ocaml中,元组(1, "one")
被认为具有类型int * string
,其符合Cartesian product in mathematics(即,该平面是R ^ 2 = R * R)。此外,通过nth
索引访问元组被认为是单一的。
由于其多态性,元组几乎可以被认为是一个记录/对象,它通常更喜欢像a.fieldName
这样的点符号作为访问其字段的约定(除了处理对象的Javascript之类的语言)像字典一样,允许像a["fieldname"]
这样的字符串文字访问。我唯一知道使用索引语法访问字段的语言是Lua。
就我个人而言,我认为像a.(0)
这样的语法往往看起来比a.0
更好,但这可能是有意(或没有)尴尬的,因为在大多数函数式语言中,对于元组进行模式匹配是理想的。通过其索引访问它。由于Rust也是必不可少的,因此像a.10
这样的语法可以很好地提醒模式匹配或者使用结构&#34;已经