rust启动错误ple_从错误处理看 Rust 的语言和 Go 语言的设计

golang 对比

先用go语言做一个对比,比如我们要将两个字符串转换为数字后返回结果,如果使用golang,则实现方式如下:

func multiply(first_number string, second_number string) (result int, err error) {

var (

first int

second int

)

first, err = strconv.Atoi(first_number)

if err != nil {

return

}

second, err = strconv.Atoi(second_number)

if err != nil {

return

}

result = first * second

return

}

可以看到,这也是go语言最常用的错误处理机制,如果捕获到错误,则将错误返回,否则返回正常的结果。这样处理错误的结果就是:每一个错误都要进行人肉处理,怎么很多的冗余性代码,如果代码量很大的话,会写很多冗余的代码,很不优雅。

rust 实现

基础版本

现在,使用Rust进行实现同样的逻辑:

fn multiply(first_number_str: &str, second_number_str: &str) -> i32 {

let first_number = first_number_str.parse::().unwrap();

let second_number = second_number_str.parse::().unwrap();

first_number * second_number

}

以上代码相比golang的代码,并没有多少现金的地方。因为程序在解析到程序异常的时候,直接终止程序。这样在项目开发中是很不友好的,但是,这个只是最粗糙的实现方式,我们使用match进行优化它:

match

use std::num::ParseIntError;

type AliasResult = Result;

#[allow(dead_code)]

fn multiply1(first_number_str: &str, second_number_str: &str) -> AliasResult {

match first_number_str.parse::() {

Err(e) => Err(e),

Ok(first_number) => match second_number_str.parse::() {

Err(e) => Err(e),

Ok(second_number) => Ok(first_number * second_number)

}

}

}

这个和golang相比,实现不相上下。都是检测到异常就返回异常,如果止步于此,那么,rust只能和golang打成平手。但是,rust还提供的函数式的结果处理机制:

使用 map 和 and_then 实现

#[allow(dead_code)]

fn multiply2(first_number_str: &str, second_number_str: &str) -> AliasResult {

first_number_str.parse::().and_then(|first_number| {

second_number_str.parse::().map(|second_number| first_number * second_number)

})

}

可以看到,通过算子的方式,rust可以通过两行代码就可以处理想要的结果,这里已经是相对比较好的实现了。但是,相比之前的代码,不过不了解函数式编程,可能相对难懂。那么我们有没有折中的实现呢

通用折中的实现

#[allow(dead_code)]

fn multiply3(first_number_str: &str, second_number_str: &str) -> AliasResult {

let first_number = match first_number_str.parse::() {

Ok(first_number) => first_number,

Err(e) => return Err(e)

};

let second_number = match second_number_str.parse::() {

Ok(second_number) => second_number,

Err(e) => return Err(e)

};

Ok(first_number * second_number)

}

以上实现,相对来说清晰易读,但是,有没有一种方式,能将重复的错误处理简化掉呢,答案是有:

#[allow(dead_code)]

fn multiply4(first_number_str: &str, second_number_str: &str) -> AliasResult {

let first_number = first_number_str.parse::()?;

let second_number = second_number_str.parse::()?;

Ok(first_number * second_number)

}

以上实现,相比之前第一个最粗糙的实现,只是多了两个?.但是,他依然做了最安全的错误处理,同时,相比于golang,代码量成倍的减少,并且代码的易读性也相当的高,同时,相比代码的执行效率,rust也是完胜golang的。所以,拥抱rust吧~~

本作品采用《CC 协议》,转载必须注明作者和本文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值