Rust:闭包组合所有权
Rust: Closure composition ownership
为了避免嵌套匹配,我尝试对 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。
第一个片段被编译器接受,第二个不接受。
编译器向我发出以下错误消息:
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
,但错误消息是相同的。
为什么第二个片段中的所有权是错误的,哪种是写这样的东西的惯用方式?
问题是 conn.prepare
returns 引用 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"));
}
}
并让调用者处理错误。如果您想自己处理错误,可以将上述代码包装在局部函数或闭包中(另请参阅 )。
为了避免嵌套匹配,我尝试对 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。
第一个片段被编译器接受,第二个不接受。 编译器向我发出以下错误消息:
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
,但错误消息是相同的。
为什么第二个片段中的所有权是错误的,哪种是写这样的东西的惯用方式?
问题是 conn.prepare
returns 引用 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"));
}
}
并让调用者处理错误。如果您想自己处理错误,可以将上述代码包装在局部函数或闭包中(另请参阅