Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Error handling 问号运算符如何转换错误类型?_Error Handling_Rust - Fatal编程技术网

Error handling 问号运算符如何转换错误类型?

Error handling 问号运算符如何转换错误类型?,error-handling,rust,Error Handling,Rust,这不会编译: fn foo()->std::io::Result{ 待办事项!() } pub fn bar()->无论如何::结果{ foo() } 这也不是: pub fn bar()->无论如何::结果{ foo().into() } 但这确实: pub fn bar()->无论如何::结果{ Ok(foo()?) } ?转换背后的机制是什么?有没有比Ok(…?)?更好的转换方法 //r? 火柴{ Ok(v)=>v, Err(x)=>返回Err(std::convert::Into:

这不会编译:

fn foo()->std::io::Result{
待办事项!()
}
pub fn bar()->无论如何::结果{
foo()
}
这也不是:

pub fn bar()->无论如何::结果{
foo().into()
}
但这确实:

pub fn bar()->无论如何::结果{
Ok(foo()?)
}
转换背后的机制是什么?有没有比
Ok(…?)

更好的转换方法

//r?
火柴{
Ok(v)=>v,
Err(x)=>返回Err(std::convert::Into::Into(x)),
}
最后一段代码是这样的:

pub fn bar()->无论如何::结果{
Ok(匹配foo(){
Ok(x)=>x,
Err(x)=>返回Err(std::convert::Into::Into(x)),
})
}
或者这个:

pub fn bar()->无论如何::结果{
设r:()=匹配foo(){
Ok(x)=>x,
Err(x)=>返回Err(std::convert::Into::Into(x)),
};
Ok(r)
}
UPD

正如@masklin所说,它使用From trait代替Into和trait。 你可以学到更多。 这非常令人惊讶,因为trait的文档中说:

在泛型函数上指定特征边界时,更喜欢使用Into而不是From,以确保也可以使用仅实现Into的类型

最后,结果代码如下所示:

pub fn bar()->无论如何::结果{
让r:()=将Try::匹配到_结果(foo()){
Ok(x)=>x,
Err(e)=>返回Try::from_error(from::from(e)),
};
Ok(r)
}

放在
结果
值之后。因为传播错误模式在rust中很常见,所以它提供了
作为它们的简写。例如:

使用std::io;
使用std::io::Read;
使用std::fs::File;
pub fn read(文件名:&str)->结果{
让f=File::open(filename);//我们正在尝试读取文件,当作用域结束时,该文件将被删除
如果一切正常,让mut f=match f{//
确定(文件)=>文件,
Err(e)=>返回Err(e),
};
让mut s=String::new();
将f.read_匹配到_字符串(&mut s){//如果一切正常,则将所有文件放入s中
正常()=>正常,
误差(e)=>误差(e),
}
}
下面和上面的代码执行相同的操作:

使用std::io::Read;
使用std::fs::File;
使用std::io;
pub fn read(文件名:&str)->结果{
让mut f=File::open(filename)?;
让mut s=String::new();
f、 读取到字符串(&M)?;
好(s)
}
您甚至可以链接
运算符:

使用std::io;
使用std::fs::File;
使用std::io::Read;
pub fn read(文件名:&str)->结果{
让mut s=String::new();
文件::打开(文件名)?。读取字符串(&M)?;
好(s)
}
但是
匹配表达式之间有区别:
操作符也调用
from
,这是在
from
trait中定义的,它将一种错误类型转换为另一种错误类型。这意味着,当函数返回
std::io::Error
但在函数
中出现其他类型的错误时,
将其转换为
std::io::Error


也许您会喜欢。您可能希望转换错误,而不是保留错误的结果-即
foo()。映射错误(Into::Into)
而不是
foo()。Into()
。绝对同意。“如何正确处理错误?”和“解释如何删除此运算符”的问题如何相同@Shepmaster“问号运算符如何转换错误类型?”;“转换背后的机制是什么?会”-来自重复:“那么问号操作符将能够将任何兼容的错误转换为这些类型中的一种,因为不同的Into-and-from-trait实现。”一个简短的评论隐藏在一个长答案中。标题是同一个问题,但是如果你真的读了这个问题,你可以看到他在问如何从一种错误类型转换为另一种错误类型,他不是在问
实现这一点的机制。FWIW
试试宏从
而不是从到,我不记得确切的原因(可能是Into的推理问题?)。还有第二个特性。@masklin这让我很惊讶,因为在泛型函数上指定特性边界时,say
更喜欢使用Into而不是From,以确保只实现Into的类型也可以使用。
但你是对的。我会更新答案。是的,如果
转换为
有效,通常建议这样做,因为
转换为
是自动为
执行的,但它并不总是有效,因此对于宏之类的东西,风险更大。是的,我清楚地知道
的用途。我要求从
位澄清
。例如,你可以解释为什么我的
foo().into()
版本不起作用(大概我需要做类似
foo().map\u err(into::into)
?我的错,我误解了你的问题。那样的话,我还没有答案。