【问题标题】:Rust: Closure composition ownershipRust:闭包组合所有权
【发布时间】:2021-10-07 06:13:19
【问题描述】:

为了避免嵌套匹配,我尝试对Result 使用and_then 方法。当我尝试转换时出现问题

match Connection::open(&db_path) {
    Ok(conn) => {
        match conn.prepare("SELECT qwe,username_value,wer FROM my_table;") {
            Ok(mut stmt) => {
                match stmt.query_map([], |row| {Ok(row.get_unwrap::<usize, String>(1).clone())}) {
                    Ok(usernames) => {
                        for username in usernames {
                            if username.is_ok() {
                                println!("{}", username.expect("Could not read username value"));
                            }
                        }
                        println!("Query done");
                    },
                    Err(err) => println!("Error {}", err),
                }
            },
            Err(err) => println!("Error {}", err),
        }
    },
    Err(err) => println!("Error {}", err),
}

进入这个

match Connection::open(&db_path)
    .and_then(move |conn: Connection| conn.prepare("SELECT qwe,username_value,wer FROM my_table;"))
    .and_then(|mut stmt: Statement| stmt.query_map([], |row| {Ok(row.get_unwrap::<usize, String>(1).clone())})) {
    Ok(usernames) => {
        for username in usernames {
            if username.is_ok() {
                println!("{}", username.expect("Could not read username value"));
            }
        }
        println!("Query done");
    },
    Err(_) => println!("Error querying db"),
}

SQL 库是 rusqlite。

第一个 sn-p 被编译器接受,第二个不被接受。 编译器向我发出以下错误消息:

error[E0515]: cannot return value referencing function parameter `conn`
   --> src\main.rs:134:43
    |
134 |         .and_then(move |conn: Connection| conn.prepare("SELECT qwe,username_value,wer FROM my_table;"))
    |                                           ----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                                           |
    |                                           returns a value referencing data owned by the current function
    |                                           `conn` is borrowed here

error[E0515]: cannot return value referencing function parameter `stmt`
   --> src\main.rs:135:41
    |
135 |         .and_then(|mut stmt: Statement| stmt.query_map([], |row| {Ok(row.get_unwrap::<usize, String>(1).clone())})) {
    |                                         ----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                                         |
    |                                         returns a value referencing data owned by the current function
    |                                         `stmt` is borrowed here

error: aborting due to 2 previous errors

我尝试在三个闭包上使用move,但错误消息是相同的。 为什么第二个 sn-p 中的所有权错误,这是写这种东西的惯用方式?

【问题讨论】:

    标签: rust closures ownership


    【解决方案1】:

    问题在于conn.prepare 返回一个引用conn 的语句,但conn 在闭包结束时被销毁,因此当语句尝试使用它时它不再存在。做你想做的事的惯用方法是使用 ? 运算符:

    let conn = Connection::open(&db_path)?;
    let mut stmt = conn.prepare("SELECT qwe,username_value,wer FROM my_table;")?;
    for username in stmt.query_map([], |row| {Ok(row.get_unwrap::<usize, String>(1).clone())})? {
        if username.is_ok() {
            println!("{}", username.expect("Could not read username value"));
        }
    }
    

    并让调用者处理错误。如果您想自己处理错误,可以将上述代码包装在本地函数或闭包中(另请参阅this question)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 2021-09-01
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多