Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can this Rust code be written without the "match" statement?

linuxfood has created bindings for sqlite3, for which I am thankful. I'm just starting to learn Rust (0.8), and I'm trying to understand exactly what this bit of code is doing:

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;
            }
        };

I do understand basically what it is doing. It is attempting to obtain a database connection and also testing for an error. I don't understand exactly how it is doing that.

In order to better understand it, I wanted to rewrite it without the match statement, but I don't have the knowledge to do that. Is that possible? Does sqlite::open() return two variables, or only one?

How can this example be written differently without the match statement? I'm not saying that is necessary or preferable, however it may help me to learn the language.

like image 277
Brian Oh Avatar asked Oct 17 '13 05:10

Brian Oh


2 Answers

The outer statement is an assignment that assigns the value of the match expression to database. The match expression depends on the return value of sqlite::open, which probably is of type Result<T, E> (an enum with variants Ok(T) and Err(E)). In case it's Ok, the enum variant has a parameter which the match expression destructures into db and passes back this value (therefore it gets assigned to the variable database). In case it's Err, the enum variant has a parameter with an error object which is printed and the function returns.

Without using a match statement, this could be written like the following (just because you explicitly asked for not using match - most people will considered this bad coding style):

let res = sqlite::open("test.db");
if res.is_err() {
    println!("Error opening test.db: {:?}", res.unwrap_err());
    return;
}
let database = res.unwrap();
like image 129
Zargony Avatar answered Sep 20 '22 16:09

Zargony


I'm just learning Rust myself, but this is another way of dealing with this.

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

See the documentation about if let.

like image 26
Dave Hylands Avatar answered Sep 20 '22 16:09

Dave Hylands