Rust 如何将结果映射为数字错误代码?
我使用C调用了一系列FFI函数。调用方希望成功时为1,失败时为-1 结构错误; fn我的生锈函数->结果{ 好啊 } [allownon_snake_案件] pub extern C fn从\u C->i32调用\u{ 让结果=我的函数; 比赛结果{ 好的=>1, 错误=>-1, } } 有没有更惯用的方法将我的结果转换为1/-1返回代码?您可以使用它创建一个类型,在该类型中可以实现并且仍然表示i32,这允许编译检查您是否正确地转换了结果,前提是您的from实现中没有bug,因此可能需要添加一些单元测试 类型MyResult=Result; fn my\u rust\u函数->MyResult{ 好啊 } [报告透明] 发布结构结果{ 代码:i32, //代码:libc::c_int,//如果您的c库期望的是'c_int',而不是'i32` } 从中为CResult执行impl{ fn fromresult:MyResult->Self{ 让代码=匹配结果{ 好的=>1, 错误=>-1, }; 自我{代码} } } [allownon_snake_案件] pub extern C fn从\u C->CResult调用\u{ 让结果=我的函数; 结果 } 您还可以将枚举用于: [现场][32] pub enum CResult{ NoError=1, 错误=-1, } 从中为CResult执行impl{ fn fromresult:MyResult->Self{ 比赛结果{ 好的=>CResult::NoError, Err_uz=>CResult::Error, } } } 在夜间,您还可以实施: ![特征特征] 使用std::ops::Try; 类型MyResult=Result; fn my\u rust\u函数->MyResult{ 好啊 } [现场][32] pub enum CResult{ NoError=1, 错误=-1, } 从中为CResult执行impl{ fn fromresult:MyResult->Self{ 比赛结果{ 好的=>CResult::NoError, Err_uz=>CResult::Error, } } } 从中为MyResult执行impl{ fn fromcresult:CResult->Self{ 比赛成绩{ CResult::NoError=>Ok, CResult::Error=>Err, } } } 求结果{ 类型Ok=; 类型错误=; fn进入_resultself->MyResult{ 自我陶醉 } fn from_ok_:::ok->Self{ 无错误 } fn来自_错误:::错误->自我{ Self::错误 } } [allownon_snake_案件] pub extern C fn从\u C->CResult调用\u{ 让u=我的函数?; CResult::NoError } 注意:使用枚举方法时要小心,确保您的实现是兼容的。[reprlibc::c_int]是我们真正想要的,但我不知道用什么方式来表达这一点。因此,如果库需要c_int,那么具有reprttransparent的结构可能更安全。我会创建一个扩展特性: 另见:Rust 如何将结果映射为数字错误代码?,rust,Rust,我使用C调用了一系列FFI函数。调用方希望成功时为1,失败时为-1 结构错误; fn我的生锈函数->结果{ 好啊 } [allownon_snake_案件] pub extern C fn从\u C->i32调用\u{ 让结果=我的函数; 比赛结果{ 好的=>1, 错误=>-1, } } 有没有更惯用的方法将我的结果转换为1/-1返回代码?您可以使用它创建一个类型,在该类型中可以实现并且仍然表示i32,这允许编译检查您是否正确地转换了结果,前提是您的from实现中没有bug,因此可能需要添加一些
这就是我要做的——很清楚正在执行的是什么。您可以执行result.map | | | 1.map | err | | |-1.unwrap,但这样会创建不必要的闭包。为什么需要[ReprtTransparent]呢?这不会影响您编写代码的方式,而且我相当肯定编译器会以任何方式进行优化。@jhpratt,因为如果没有详细的答案,这将是UB。我没有想过创建枚举,但这是一个非常简洁的解决方案。我将@shepmaster response标记为答案,因为它在精神上最接近于我试图实现的目标。
trait FfiError {
fn as_c_error(&self) -> i32;
}
impl<T, E> FfiError for Result<T, E> {
fn as_c_error(&self) -> i32 {
match self {
Ok(_) => 1,
Err(_) => -1,
}
}
}
pub extern "C" fn called_from_c() -> i32 {
my_rust_function().as_c_error()
}