Chương trình của tôi sử dụng rusqlite để xây dựng cơ sở dữ liệu từ một nguồn dữ liệu khác. Cơ sở dữ liệu được xây dựng nhiều bảng theo cách tương tự, vì vậy tôi nghĩ rằng tôi muốn làm một chức năng tái sử dụng để làm như vậy:Mượn vấn đề với câu lệnh SQL đã biên dịch
fn download_generic<Inserter>(table_name: &str,
connection: &mut rusqlite::Connection,
inserter: &mut Inserter)
-> Result<(), String>
where Inserter: FnMut(&str, &json::JsonValue) ->()
{}
inserter
là một chức năng gắn kết các giá trị đúng từ một tuyên bố trước đó chuẩn bị và thực hiện chèn .
Tôi gọi nó là như thế này:
let mut insert_stmt = connection
.prepare("insert or replace into categories values(?,?);")
.unwrap();
download_generic("categories",
&mut connection,
&mut |uuid, jsonproperties| {
insert_stmt.execute(&[&uuid, &jsonproperties["name"].as_str().unwrap_or("")]);
});
Tuy nhiên tôi không thể vượt qua &mut connection
để download_generic
vì nó đã được mượn bởi insert_stmt
. Đặt nó vào một RefCell
không có ý nghĩa bởi vì tôi không cần thời gian chạy trên cao để thực hiện công việc này.
Tôi có thể thử làm cho insert_stmt
được tạo bởi lambda mà bạn chuyển đến download_generic
, nhưng sau đó tôi bị choáng ngợp vì phải thêm dấu thời gian ở mọi nơi và dường như không tự nhiên.
Đặt nó vào một 'RefCell' sẽ không hoạt động:' RefCell' chỉ cần kiểm tra tại thời gian chạy thay vì biên dịch thời gian nhưng kiểm tra cơ bản giống nhau được thực hiện => ** Aliasing XOR Mutability **. Câu hỏi hiển nhiên là: bạn không thể chỉ mượn (bất biến) cùng một kết nối? Nếu một khoản vay được yêu cầu duy nhất có thể thay đổi, thì bạn sẽ không may mắn. –
Tôi không thể di chuyển insert_stmt vào lambda bằng cách nào đó để 'download_generic' giữ nó? – njaard
Bạn có thể sử dụng 'prepar_cached' thay vì' chuẩn bị' để có được một tuyên bố chuẩn bị trong phạm vi đóng cửa thay thế không? Bạn sẽ phải vượt qua 'kết nối' để đóng cửa một cách rõ ràng để tránh mâu thuẫn với các khoản vay. –