赞
踩
不同之处主要在于用途不同
都可以用于Error handle的,都是枚举类型,都可以作为function的返回类型,
二者源码如下
pub enum Option<T> {
None,
Some(T),
}
pub enum Result<T, E> {
Ok(T),
Err(E),
}
有场景才有设计的必要,但是你可能会问,那为什么别的语言就没有这么设计,Rust这么设计的原因与Rust的语言设计理念有关,Rust想要尽力做到安全,尽力把不同的场景分开处理,当你想要在程序里设计一个Error handle流程的时候,使用Result是最好的,当你想要返回一个值但是这个值不一定存在的时候,使用Option是最好的,其实在其他语言中,这些可以直接用一个None或者Null的概念来解决,但是这并不是一个好的设计,Null的存在会将这些东西都混为一谈,在一个Null产生的时候,你无法知道究竟是因为你的算法出了问题导致的,还是因为你的输入不合法导致的,又或者是你调用的某个库内部发生了错误,因为你得到的只有一个Null,一个Null把许多不同的情况耦合到了一起,无论发生了什么你都可以返回一个Null,得到Null的人如何理解Null要看他和你的默契。
当然你可以在你的function内每个有可能产生Null的地方都加一个if,然后返回一个errorcode,或者在function内添加log部件,但是这些都不是标准,跟别人合作的时候,调用其他人库的时候,怎么办?
Null的设计者托尼·霍尔,在后来的演讲中多次提到,Null的设计是一个价值10亿美元的错误
引入Result和Option后,根据不同的场景返回不同的内容,就能确保语言的安全性,一旦你的返回值跟收到这个值的人想法不同,代码就跑不起来,直接编译都过不了,这很符合Rust的设计理念,把bug杀死在编译前。
Rust中并不是没有None,只不过是把None的level降低了很多,从一个垃圾桶,变成了一个固定的概念,None在Rust中只代表无,没有,这一个概念。
Option和Result返回值如何使用?
Option和Result都是枚举类型,都可以使用match进行内容提取。Result还可以使用unwrap和except来进行提取,如果结果是Ok则返回数据本身,如果结果是Err则直接崩溃,和panic一个效果,except相较于unwrap的区别是可以自己定义panic崩溃报错内容。
// 使用Option处理可能存在或不存在的值 fn find_element_index(arr: &[i32], target: i32) -> Option<usize> { for (index, &value) in arr.iter().enumerate() { if value == target { return Some(index); } } None } // 使用Result处理可能的错误情况 fn divide(a: i32, b: i32) -> Result<i32, &'static str> { if b == 0 { Err("Cannot divide by zero") } else { Ok(a / b) } } fn main() { let numbers = [1, 2, 3, 4, 5]; // 使用Option let index = find_element_index(&numbers, 3); match index { Some(i) => println!("Element found at index: {}", i), None => println!("Element not found"), } // 使用Result match divide(10, 2) { Ok(result) => println!("Result of division: {}", result), Err(error) => println!("Error: {}", error), } divide(10,2).unwrap(); divide(10,2).expect("defined by yourself"); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。