在编写一些试图习惯Rust的小型初级练习时,我遇到了一些我不懂的输出Vec::get
.这是代码:
fn main() {
let command = [('G', 'H'), ('H', '5')];
for i in 0..3 {
print!(" {} ", i);
println!("{:?}", command.get(i));
}
}
Run Code Online (Sandbox Code Playgroud)
输出是
0 Some(('G', 'H'))
1 Some(('H', '5'))
2 None
Run Code Online (Sandbox Code Playgroud)
我在Haskell涉足面前,我的意思是看了教程网站10分钟,跑回C++,但我记得读的东西Some
和None
Haskell的.我很惊讶在Rust看到这个.有人可以解释为什么.get()
返回Some
或None
?
huo*_*uon 34
签名get
(对于切片,不是 Vec
,因为你正在使用数组/切片)是
fn get(&self, index: usize) -> Option<&T>
Run Code Online (Sandbox Code Playgroud)
也就是说,它返回一个Option
,这是一个定义为的枚举
pub enum Option<T> {
None,
Some(T),
}
Run Code Online (Sandbox Code Playgroud)
None
并且Some
是枚举的变体,也就是说,类型的值Option<T>
可以是a None
,也可以是Some
包含type的值T
.
这与data Maybe a = Nothing | Just a
Haskell中的核心类型相同; 两者都代表一个可选值,它可以是(Some
/ Just
),也可以不是(None
/ Nothing
).
当只有一种可能导致失败的原因时,这些类型通常用于表示失败,例如,.get
用于Option
给出类型安全的边界检查数组访问:None
当索引超出界限时它返回(即没有数据),否则它返回Some
包含请求指针的a.
考虑Some
并None
作为规范的“安全”方式来解决 Rust 语言不支持“安全”使用NULL
指针这一事实。由于您的长度Vec
为 3,并且您只指定了两对,因此第三对有效NULL
;NULL
它返回而不是返回None
。
Rust 通过在编译时通过Some
/强制我们None
始终处理None
被返回的可能性来提供安全保证。
command
不是向量(类型Vec<T>
),它是固定大小的数组([(char, char); 2]
在您的情况下为类型),并且数组会自动借入切片(视图到数组),因此您可以使用切片上定义的所有方法,包括get
:
返回给定索引处的切片元素,或者
None
索引是否超出范围.
行为非常明显:当给定索引有效时,它返回Some
该索引下的元素,否则返回None
.
还有另一种方法可以访问切片中的元素 - 索引操作符,您应该熟悉它:
let nums = [1, 2, 3];
let x = nums[1];
Run Code Online (Sandbox Code Playgroud)
它直接返回切片的元素,但如果索引超出范围,它将失败当前任务:
fn main() {
let x = [1, 2];
for i in 0..3 {
println!("{}", x[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
该程序失败:
% ./main2
1
2
task '<main>' failed at 'index out of bounds: the len is 2 but the index is 2', main2.rs:4
Run Code Online (Sandbox Code Playgroud)
get()
为方便起见需要方法; 如果给定的索引有效,它可以避免提前检查.
如果你不知道什么Some
和None
真的是,为什么他们都需要在一般情况下,你应该阅读官方 教程,它解释了它,因为它是很基本的概念.
选项枚举有 2 个变体。
1-None
用于表示失败或无值
2-Some
这是包装值的元组结构
如果你需要在 OOB 中编写这个结构,例如在 中typescript
,你会这样写。这将使情况更容易可视化
将 Option 接口定义为派生类
interface Option<T = any> {
// pass all the methods here
// unwrap is used to access the wrapped value
unwrap(): T;
}
Run Code Online (Sandbox Code Playgroud)
编写Some
继承自的类Option
Some
类返回一个值
class Some<T> implements Option<T> {
private value: T;
constructor(v: T) {
this.value = v;
}
unwrap(): T {
return this.value
}}
Run Code Online (Sandbox Code Playgroud)
None
也继承自的类Option
None
类返回 null
class None<T> implements Option<T> {
// you do not need constructor here
unwrap(): T {
return null as T;
}
}
Run Code Online (Sandbox Code Playgroud)