6

linuxfood 为 sqlite3 创建了绑定,对此我表示感谢。我刚开始学习 Rust (0.8),我试图准确理解这段代码在做什么:

extern mod sqlite;

fn db() {

    let database =
        match sqlite::open("test.db") {
            Ok(db) => db,
            Err(e) => {
                println(fmt!("Error opening test.db: %?", e));
                return;
            }
        };

我基本上明白它在做什么。它正在尝试获取数据库连接并测试错误。我不明白它是如何做到的。

为了更好地理解它,我想在没有match语句的情况下重写它,但我没有这样做的知识。那可能吗?sqlite::open()返回两个变量,还是只返回一个?

match如果没有这个语句,这个例子怎么能有不同的写法呢?我并不是说这是必要的或可取的,但它可以帮助我学习语言。

4

4 回答 4

8

外部语句是将匹配表达式的值分配给 的赋值database。匹配表达式取决于 的返回值sqlite::open,它可能是类型Result<T, E>(带有变体Ok(T)和的枚举Err(E))。如果是Ok,枚举变量有一个参数,匹配表达式将其解构db并传回该值(因此它被分配给变量database)。如果是Err,则 enum 变体有一个带有错误对象的参数,该对象被打印并且函数返回。

在不使用 match 语句的情况下,可以这样写(只是因为您明确要求不使用 match - 大多数人会认为这种糟糕的编码风格):

let res = sqlite::open("test.db");
if res.is_err() {
    println!("Error opening test.db: {:?}", res.unwrap_err());
    return;
}
let database = res.unwrap();
于 2013-10-17T09:24:35.957 回答
5

我自己只是在学习 Rust,但这是另一种处理方式。

if let Ok(database) = sqlite::open("test.db") {
    // Handle success case
} else {
    // Handle error case
}

请参阅有关if let.

于 2016-03-01T00:11:12.710 回答
4

这个函数open返回SqliteResult<Database>;给定定义pub type SqliteResult<T> = Result<T, ResultCode>,即std::result::Result<Database, ResultCode>

Result是一个enum,如果不匹配,您基本上无法访问 enum 的变体:也就是说,从字面上看,这是唯一的方法。当然,你可能有一些方法可以抽象出匹配,但它们必须用 match 来实现。

您可以从 Result 文档中看到,它确实具有类似 的便捷方法is_err,大约是这样的(不完全是这样,但足够接近):

fn is_err(&self) -> bool {
    match *self {
        Ok(_) => false,
        Err(_) => true,
    }
}

unwrap(再次只是近似):

fn unwrap(self) -> T {
    match self {
        Ok(t) => t,
        Err(e) => fail!(),
    }
}

如您所见,这些是通过匹配实现的。在您的这种情况下,使用匹配是编写此代码的最佳方式。

于 2013-10-17T09:50:36.467 回答
3

sqlite::open()正在返回一个枚举。枚举在 rust 方面略有不同,枚举的每个值都可以附加字段。
http://static.rust-lang.org/doc/0.8/tutorial.html#enums

因此,在这种情况下,SqliteResult枚举可以是Ok或者Err如果是Ok则它具有对附加到它的数据库的引用,如果是Err则它具有错误详细信息。

具有 C# 或 Java 背景的您可以将其SqliteResult视为基类OkErr从中继承,每个基类都有自己的相关信息。在这种情况下,match 子句只是检查类型以查看返回的子类型。我不会太专注于这种平行,尽管尝试如此努力地匹配语言之间的概念是一个坏主意。

于 2013-10-17T07:50:28.053 回答