Rust特殊枚举Option用法( 二 )

`|= help: the trait `std::ops::Add>` is not implemented for `i8`error: aborting due to previous errorFor more information about this error, try `rustc --explain E0277`.error: could not compile `enums`.To learn more, run the command again with --verbose.激烈!实际上 , 此错误消息表示Rust不了解如何添加i8和Option , 因为它们是不同的类型 。 当我们具有i8Rust中类似类型的值时 , 编译器将确保我们始终具有有效值 。 我们可以放心地进行操作 , 而不必在使用该值之前检查null 。 只有当我们有一个Option(或我们正在使用的任何类型的值)时 , 我们才需要担心可能没有值 , 并且编译器将确保我们在使用该值之前处理该情况 。
换句话说 , 您必须先将转换为Option , T然后才能对其执行T操作 。 通常 , 这有助于捕获null最常见的问题之一:假设某事物实际上并非为null 。
不必担心会错误地假设一个非空值 , 这有助于您对代码更有信心 。 为了拥有一个可能为null的值 , 您必须通过设置value的类型来明确选择加入Option 。 然后 , 当您使用该值时 , 要求您显式处理该值为null的情况 。 每个值的类型都不是 Option , 您可以放心地假设该值不为null 。 对于Rust来说 , 这是一个故意的设计决策 , 旨在限制null的普遍性并提高Rust代码的安全性 。
Rust特殊枚举Option用法文章插图
那么 , 当您拥有类型的值以便可以使用该值时 , 如何T从Some变量中获取Option值呢?该Option枚举具有大量的是在各种情况下有用的方法; 您可以在文档中查看它们 。 Option在使用Rust的过程中 , 熟悉其中的方法将非常有用 。
通常 , 为了使用Option值 , 您需要具有可处理每个变量的代码 。 您需要一些仅在具有Some(T)值时才运行的代码, 并且允许该代码使用inner T 。 如果您有一个None值 , 那么您希望其他一些代码运行 , 而该代码没有T 可用的值 。 该match表达式是一个控制流构造 , 与枚举一起使用时会执行此操作:它将运行不同的代码 , 具体取决于它具有的枚举的变体形式 , 并且该代码可以使用匹配值内的数据 。
这里的None就是和空值表达类似的东西 。 那为什么要使用None而不是空值呢?这里有一个很重要的一点 , Option和T不是同一个类型 。 不要小看着一个简单的区别 , 这意味着Option和T是不能直接进行运算的 , 即Option和i32是不能直接相加的 。 实际上 , 更进一步的 , 在对Option进行T的运算时 , 必须先将Option转化成T类型 。 如此一来就可以帮助我们避免以为值非空而实际为空的情况 。 例如下面这段代码:
fn main() {let a: i32 = 1;let b: Option = Some(5);let c = a + b;println!("{}", c);}编译器会报如下错误
error[E0277]: cannot add `std::option::Option` to `i32` --> src/main.rs:4:15|4 |let c = a + b;|^ no implementation for `i32 + std::option::Option`|= help: the trait `std::ops::Add>` is not implementedfor `i32`error: aborting due to previous error我们必须先将b从Option类型转化为i32才能进行i32类型的运算 。 如下
fn main() {let a: i32 = 1;let b: Option = Some(5);let c = a + b.unwrap();println!("{}", c);}另外 , 每当我们引入一个可能为空的值时 , 我们必须先把它放到Option里 。 当我们使用这个值时 , 我们必须先处理值为空的情况 。 也就是说 , 只要一个值不是Option类型的 , 我们就可以认定它的值不为空 。
这个设计相当有意思 , 我又查了一些资料发现scala里就存在这个设计 , rust应该就是借鉴的scala的做法 , 无怪乎有人说rust参考了c/c++和haskell/scala两类语言 。 如果有机会应该多见识一下其他的语言 , 开阔下思路(虽然工作估计还是c/c++ , (-_-||)