繁体   English   中英

在 rust 中实例化错误时出现问题

[英]Problems while instantiating an error in rust

我有一个结构,其中包含返回代码和从 postgres 查询中检索到的数据。 我有一个初始化结构的 new() function:

impl <T> Response <T>
     {
     pub fn new() -> Response <T>
             {
             return Response
                 {
                 rc : RetCode::Ok,
 ------>         pg_err : Error::new(),
                 desc : "".to_string(),
                 data : Vec::new(), 
                 id : 0,
                }

但是 postgres::Error::new() 是私有的。 有没有办法创建一个新的错误(我不介意类型或内容),只是为了实际的未来错误的占位符? 我不需要 Null,只是一个假错误,因为在 RetCode 中我有 ok,no-data-retrived,postgre 错误,所以我需要在 retcode 为 pg_error 时检查错误。

正如评论中提到的,没有公开的方法来创建postgres::Error 您只能从其他一些失败的 postgres 操作中获得一个。 您可以使用链接的答案并使用Option在发生错误之前使用None创建pg_err ,并在错误发生时使用Some(...)填充它。

但是,这不是您应该解决此特定问题的方式。 您有一个单一类型,旨在表达多个不同的 forms 响应:“ok”、“no-data”和“error”,正如您在评论中提到的那样。 所以听起来你的RetCode是这样设计的:

enum RetCode { Ok, NoData, Error }

但是 Rust enum比其他语言强大得多,它们可以保存特定变体专有的数据。 有一种哲学是“使无效状态无法代表”。 换句话说,如果没有发生错误,为什么会有pg_err呢? 如果状态为NoData ,为什么还要有一个data字段?

您可以像这样重组对象:

enum ResponseKind<T> {
    Ok { data: Vec<T> },
    NoData,
    Error { pg_err: postgres::Error },
}

struct Response<T> {
    id: i32,
    desc: String,
    kind: ResponseKind<T>,
}

这样您就不必担心创建一些虚拟错误类型。

您应该注意其他评论; 不要陷入仅仅为了它而简单地创建一个虚拟构造函数的陷阱。 new()只是一个约定,如果您的类型没有明显的默认 state,则不应遵循该约定。 您应该具有带有参数的构造函数,这些参数提供有效数据来构造它。 喜欢:

impl<T> Response<T> {
    pub fn ok(id: i32, desc: String, data: Vec<T>) -> Response<T> {
        // or maybe id and desc are generated or dependent on
        // kind and don't need to be parameters?
        Response {
            id,
            desc,
            kind: ResponseKind::Ok { data },
        }
    }

    pub fn no_data(id: i32, desc: String) -> Response<T> { ... }
    pub fn error(id: i32, desc: String, error: Error) -> Response<T> { ... }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM