Sqlite 此防锈代码是否可以在没有“防锈”的情况下编写;匹配“;陈述
,对此我表示感谢。我刚刚开始学习Rust(0.8),我正试图准确理解这段代码的作用:Sqlite 此防锈代码是否可以在没有“防锈”的情况下编写;匹配“;陈述,sqlite,rust,rust-0.8,Sqlite,Rust,Rust 0.8,,对此我表示感谢。我刚刚开始学习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))
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
语句,该示例如何以不同的方式编写?我并不是说这是必要的或更可取的,但是它可能会帮助我学习该语言。sqlite::open()
正在返回一个枚举。枚举有点不同,枚举的每个值都可以附加字段。看 因此,在这种情况下,
SqliteResult
enum可以是Ok
或Err
如果是Ok
,那么它有附加到db的引用,如果是Err
,那么它有错误详细信息
使用C或java背景,可以将
数据库。匹配表达式取决于sqlite::open
的返回值,其类型可能为Result
(带有变量Ok(T)
和Err(E)
)的枚举)。如果是Ok
,则枚举变量有一个参数,匹配表达式将该参数分解为db
,并传回该值(因此将其分配给变量数据库
)。如果是Err
,则枚举变量有一个带有错误对象的参数,该参数将被打印,函数将返回
如果不使用match语句,可以这样编写(只是因为您明确要求不使用match-大多数人会认为这种编码风格不好):
);给定定义,即
Result
是一个变量,如果不进行匹配,您根本无法访问枚举的变量:这是唯一的方法。当然,您可能有用于提取匹配的方法,但它们必须使用匹配来实现
您可以从结果文档中看到,它确实有一些方便的方法,如is_err
,大致是这样的(不完全是这样,但足够接近):
和展开
(同样仅为近似值):
如您所见,这些都是通过匹配实现的。在您的例子中,使用匹配是编写此代码的最佳方式。我只是在自学,但这是另一种处理方法
if let Ok(database) = sqlite::open("test.db") {
// Handle success case
} else {
// Handle error case
}
请参阅。,意思是“结果”
(然后请参阅文档以了解其定义以及可以使用它执行的操作)。此代码就是我回答问题的方式。从这里,我们可以了解到的定义,然后是方法。您可以看到unwrap
使用match
,在一种情况下,它会导致失败代码>。这就是为什么这被认为是糟糕的风格:在运行时有可能出现故障。match
更可取的原因是编译器确保您显式地处理每种情况。(编辑:修正SO标记)谢谢你的帖子。我不得不做以下小改动,以使这项工作“println(fmt!(“Error opening test.db:%?”,res));”。虽然我通常不会这样编写代码,但它确实让我更好地理解正在发生的事情。我不想听起来很迂腐,但Result
实际上是一个枚举,而不是一个结构但你是对的,match
防锈效果很好。一方面,它确保您不会意外忘记处理案例,因为匹配构造必须是详尽的。另一方面,它提供了分解结构,以便轻松访问数据结构的内部组件。人们通常不想避免而是鼓励使用match
@BrianOh我将截取的代码改为使用println(fmt!(…)
,所以它像以前一样工作。(println!
使用format!
而不是fmt!
,并使用稍有不同的格式语法(在下一版本中,afaik将是默认的格式语法))fmt!现在已经从语言中删除了。因此,使用新方法是一个更好的想法;正如在0.8中一样,我已经更新了Forward-compatibility的答案。作为记录,if-let
在2013年提出此问题时不可用。不过,这并不意味着你的答案有任何错误。:)
fn is_err(&self) -> bool {
match *self {
Ok(_) => false,
Err(_) => true,
}
}
fn unwrap(self) -> T {
match self {
Ok(t) => t,
Err(e) => fail!(),
}
}
if let Ok(database) = sqlite::open("test.db") {
// Handle success case
} else {
// Handle error case
}