在编写一些试图习惯Rust的小型初级练习时,我遇到了一些我不了解Vec::get
的输出。这是代码:
fn main() {
let command = [('G', 'H'), ('H', '5')];
for i in 0..3 {
print!(" {} ", i);
println!("{:?}", command.get(i));
}
}
输出
0 Some(('G', 'H'))
1 Some(('H', '5'))
2 None
之前我曾经涉足过Haskell,我的意思是看一个教程网站10分钟然后回到C ++,但我记得有些关于Some
和None
的内容哈斯克尔。我很惊讶在Rust看到这个。有人可以解释为什么.get()
会返回Some
或None
吗?
答案 0 :(得分:33)
get
的签名(对于切片,不 Vec
,因为您正在使用数组/切片)
fn get(&self, index: usize) -> Option<&T>
也就是说,它返回Option
,这是一个定义为
pub enum Option<T> {
None,
Some(T),
}
None
和Some
是枚举的变体,即类型为Option<T>
的值可以是None
,或者它可以是包含Some
类型值的T
。
这与Haskell中的核心data Maybe a = Nothing | Just a
类型相同;两者都代表一个可选值,它可以是(Some
/ Just
),也可以不是(None
/ Nothing
)。
当只有一种可能导致失败的原因时,这些类型通常用于表示失败,例如,.get
使用Option
来提供类型安全的边界检查数组访问:它返回{{当索引超出范围时,1}}(即没有数据),否则返回包含请求指针的None
。
答案 1 :(得分:6)
command
不是向量(类型Vec<T>
),它是一个固定大小的数组(在您的情况下为类型[(char, char); 2]
),并且数组会自动借入切片(视图到数组),因此您可以使用切片上定义的所有方法,包括get
:
返回给定索引处切片的元素,如果索引超出范围,则返回
None
。
行为非常明显:当给定索引有效时,它返回Some
,该元素位于该索引下,否则返回None
。
还有另一种方法可以访问切片中的元素 - 索引操作符,您应该对此很熟悉:
let nums = [1, 2, 3];
let x = nums[1];
它直接返回切片的元素,但如果索引超出范围,它将失败当前任务:
fn main() {
let x = [1, 2];
for i in 0..3 {
println!("{}", x[i]);
}
}
此程序失败:
% ./main2
1
2
task '<main>' failed at 'index out of bounds: the len is 2 but the index is 2', main2.rs:4
为方便起见,需要 get()
方法;如果给定的索引有效,它可以使您免于提前检查。
如果你不知道Some
和None
到底是什么以及为什么一般需要它们,你应该阅读official tutorial,它解释因为它是非常基本的概念。
答案 2 :(得分:3)
将Some
和None
视为解决Rust语言不支持“{1}}指针”安全“使用这一事实的规范”安全“方式。由于NULL
的长度为3,而您只指定了两对,因此第三对有效Vec
;而不是返回NULL
,而是返回NULL
。
Rust通过强迫我们在编译时通过None
/ Some
来提供安全保障,以便始终处理None
被返回的可能性。