Error handling Rust中的合成错误:Ok上的浓缩结果
我有以下代码。它起作用了 但我更感兴趣的是编写Error handling Rust中的合成错误:Ok上的浓缩结果,error-handling,rust,Error Handling,Rust,我有以下代码。它起作用了 但我更感兴趣的是编写泡茶,其中我调用了两个函数:从奶牛那里获取牛奶和倒牛奶。它们都返回结果 如何编写它们,以便在它们成功的情况下继续浓缩Strings,否则返回错误 enum TeaError { NoMilk, NoCup, NoCow, NoGas, NoSomething, } fn get_milk_from_cow(cow: bool) -> Result<String, TeaError> {
泡茶
,其中我调用了两个函数:从奶牛那里获取牛奶
和倒牛奶
。它们都返回结果
如何编写它们,以便在它们成功的情况下继续浓缩String
s,否则返回错误
enum TeaError {
NoMilk,
NoCup,
NoCow,
NoGas,
NoSomething,
}
fn get_milk_from_cow(cow: bool) -> Result<String, TeaError> {
if cow {
Ok(String::from("get milk from cow"))
} else {
Err(TeaError::NoCow)
}
}
fn pour_milk(milk: bool) -> Result<String, TeaError> {
if milk {
Ok(String::from("poured milk"))
} else {
Err(TeaError::NoMilk)
}
}
fn make_tea() -> Result<String, TeaError> {
let mut process = String::new();
let step_cow = get_milk_from_cow(true)?;
let step_milk = pour_milk(true)?;
process.push_str(step_cow.as_str());
process.push_str(step_milk.as_str());
Ok(process)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn attemp_tea_one() {
match pour_milk(false) {
Err(v) => match v {
TeaError::NoMilk => assert!(true),
_ => assert!(false)
},
Ok(_) => assert!(false)
};
}
#[test]
fn attemp_tea_two() {
match make_tea() {
Err(_) => assert!(false),
Ok(_) => assert!(true)
};
}
}
但它给出了:
错误[E0308]:类型不匹配
-->src/errors.rs:27:22
|
27 |过程。推动(从奶牛身上获取牛奶(正确)?推动(倾倒牛奶(正确)?作为牛奶();
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
=注意:应为类型“%str”`
找到类型“%1”()`
aspush\u str
不返回字符串
编辑:
fn append(s1: String, s2: String) -> String {
s1 + s2.as_str()
}
fn make_tea() -> Result<String, TeaError> {
let process = append(get_milk_from_cow(true)?,
pour_milk(true)?);
Ok(process)
}
fn追加(s1:String,s2:String)->String{
s1+s2.as_str()
}
fn泡茶()->结果{
let process=append(从奶牛身上获取牛奶)(真)?,
倒牛奶(真的);
Ok(流程)
}
所以,我可以做append(append(funcA(),funcB()),funcC())
等等。。
我仍在学习生命周期,并思考是否仍然可以改进内存分配。第一件事:上面的代码似乎没有什么问题,但我假设您正在寻找更地道的代码 虽然比您的方法需要稍多的内存,但是连接字符串结果的最优雅的方法是:
fn make_tea() -> Result<String, TeaError> {
vec![get_milk_from_cow(true), pour_milk(true)].into_iter()
.collect()
}
必须创建向量,因为数组不提供所属元素的迭代器(
&T
而不是T
)。但是,我们可以通过一个额外的映射来解决这个问题:
fn make_tea() -> Result<String, TeaError> {
Ok([get_milk_from_cow(true)?, pour_milk(true)?].into_iter()
.map(|a| a.as_str())
.collect())
}
fn泡茶()->结果{
好的([从母牛那里得到牛奶(真的)?,把牛奶(真的)?)倒进冰箱()
.map(|a | a.as_str())
.collect())
}
这将把
&String
中的元素映射到&str
,同样可以收集到这些元素。第一件事:上面的代码似乎没有什么问题,但我假设您正在寻找更地道的东西
虽然比您的方法需要稍多的内存,但是连接字符串结果的最优雅的方法是:
fn make_tea() -> Result<String, TeaError> {
vec![get_milk_from_cow(true), pour_milk(true)].into_iter()
.collect()
}
必须创建向量,因为数组不提供所属元素的迭代器(
&T
而不是T
)。但是,我们可以通过一个额外的映射来解决这个问题:
fn make_tea() -> Result<String, TeaError> {
Ok([get_milk_from_cow(true)?, pour_milk(true)?].into_iter()
.map(|a| a.as_str())
.collect())
}
fn泡茶()->结果{
好的([从母牛那里得到牛奶(真的)?,把牛奶(真的)?)倒进冰箱()
.map(|a | a.as_str())
.collect())
}
这将把
&String
中的元素映射到&str
,可以同样地收集这些元素。此代码在带星号的行上执行冗余工作:
fn make_tea() -> Result<String, TeaError> {
* let mut process = String::new();
let step_cow = get_milk_from_cow(true)?;
let step_milk = pour_milk(true)?;
* process.push_str(step_cow.as_str());
process.push_str(step_milk.as_str());
Ok(process)
}
或者更方便地说
fn make_tea() -> Result<String, TeaError> {
Ok(get_milk_from_cow(true)? + &pour_milk(true)?)
}
fn泡茶()->结果{
好的(从奶牛身上取牛奶(正确)?+&倒牛奶(正确)?)
}
此代码在星号行上执行冗余工作:
fn make_tea() -> Result<String, TeaError> {
* let mut process = String::new();
let step_cow = get_milk_from_cow(true)?;
let step_milk = pour_milk(true)?;
* process.push_str(step_cow.as_str());
process.push_str(step_milk.as_str());
Ok(process)
}
或者更方便地说
fn make_tea() -> Result<String, TeaError> {
Ok(get_milk_from_cow(true)? + &pour_milk(true)?)
}
fn泡茶()->结果{
好的(从奶牛身上取牛奶(正确)?+&倒牛奶(正确)?)
}
如果图片中没有结果
,也就是说,如果从奶牛那里得到牛奶
和倒牛奶
返回字符串
s,你会怎么做?@user4815162342倒牛奶
是任何可能失败的功能的象征。我的观点是,问题不在于这些功能失败(由?
操作符负责),但是在推送str
返回()
中,请告诉我们当结果不存在时,您将如何连接字符串,以便更好地理解您希望通过结果
@user4815162342实现什么。谢谢您的问题,我想我已经找到了(可能效率低下)解决方案,思考你的问题。如果图片中没有结果
,也就是说,如果从奶牛那里得到牛奶
和倒牛奶
返回字符串
s,你会怎么做?@user4815162342倒牛奶
是任何可能失败的函数的象征。我的观点是,问题不在于那些函数失败(由?
操作符负责),但是在推送str
返回()
中,请告诉我们当结果不存在时,您将如何连接字符串,以便更好地理解您希望通过结果
@user4815162342实现什么。谢谢您的问题,我想我已经找到了(可能效率低下)解决方案,思考您的问题..但在我的代码中,第一个错误一旦发生就会传播。即,不再需要进一步的电话来泡茶。即,如果从奶牛那里获取牛奶失败倾倒牛奶将不会被调用。我认为这就是?
的目的。我认为这不是vec解决方案中会发生的情况。AshishNegi是正确的。你应该考虑改进你的问题以避免进一步的混淆。你最好使用<代码> [GETZYMKYROFRONSFOW(TRUE)?& PulyCalm(True)]?
,因为它比较短并且是预先分配的。@Veedrac似乎是由不稳定的traitSliceConcatExt
提供的,我不想使用它。@E_net4,从2015年8月开始。但是在我的代码中,第一个错误一发生就传播开来。也就是说,泡茶就不再需要更多的电话了。也就是说,如果从奶牛那里得到牛奶
失败<代码> PuluS奶将不被调用。我认为这是<代码> >代码>。我认为这不是在你的VEC解决方案中会发生的。@ AshishNegi是真的。你应该考虑改进你的问题以避免进一步的混淆。你最好使用<代码> [& GETYMIKYROFROXYBOY(TRUE)?& PulyMalk(真)?]
,因为它较短且预先分配。@Veedrac似乎是由不稳定的traitSliceConcatExt
提供的,我不想使用它。@E_net4,自2015年8月起。