Tôi có các bộ sưu tập được bán trên đĩa. Khi được yêu cầu, các bộ sưu tập này sẽ được truy xuất (không có vấn đề gì) và cần phải xây dựng một bộ sưu tập iterator
để trả về các tham chiếu đến các giá trị đã truy xuất.Lặp lại bộ sưu tập. Thả nó ngay sau khi Iterator bị xóa
Sau khi số iterator
bị xóa, tôi không cần bộ sưu tập nữa. Tôi cũng muốn nó bị bỏ.
Những gì tôi đã cố gắng cho đến nay:
Các
Iterator
sở hữu bộ sưu tập. Điều này có ý nghĩa nhất đối với tôi, nhưng điều đó là không thể; Tôi không hoàn toàn chắc chắn tại sao. Một số người nói rằng chữ ký phương thức của các đặc điểmIterator
chonext
là vấn đề. (example)Đếm tham chiếu:
Retriever
trả vềRc<Vec<usize>>
. Tôi chạy vào các vấn đề tương tự như trong iterator sở hữu. (example)Cho phép trình thu thập sở hữu bộ sưu tập và đưa ra một tham chiếu đến bộ sưu tập đó. Tôi đã cố gắng để thực hiện các retriever với mutability nội thất (
RefCell<HashMap>
), nhưng tôi không thể trở lại tài liệu tham khảo vàoHashMap
với tuổi thọ đủ dài.
Tôi thấy hai khả năng cơ bản với điều này.
Quyền truy xuất chuyển quyền sở hữu. Sau đó,
Iterator
sẽ cần phải sở hữu dữ liệu. Nội dung nào đó trong dòng:use std::slice::Iter; fn retrieve(id: usize) -> Vec<usize> { //Create Data out of the blue (or disk, or memory, or network. I dont care) //Move the data out. Transfer ownership let data = vec![0, 1, 2, 3]; data } fn consume_iterator<'a, TIterator: Iterator<Item=&'a usize>>(iterator: TIterator) { for i in iterator { println!("{}", i); } } fn handler<'a>(id: usize) -> Iter<'a, usize> { //handle_request now owns the vector. //I now want to build an owning iterator.. //This does of course not compile as vector will be dropped at the end of this method retrieve(id).iter() } fn main() { consume_iterator(handler(0)) }
Trình truy xuất sở hữu bộ sưu tập. Nhưng sau đó có hai vấn đề mới phát sinh:
- Làm cách nào để thả dữ liệu khi trình vòng lặp nằm ngoài phạm vi?
- Làm cách nào để nói với người mượn tiền rằng tôi sẽ sở hữu bộ sưu tập đủ lâu?
use std::cell::{Ref, RefCell}; struct Retriever { //Own the data. But I want it to be dropped as soon as the references to it go out of scope. data: RefCell<Vec<usize>> } impl Retriever{ fn retrieve<'a>(&'a self, id: usize) -> Ref<'a, Vec<usize>> { //Create Data out of the blue (or disk, or memory, or network. I dont care) //Now data can be stored internally and a referece to it can be supplied. let mut data = self.data.borrow_mut(); *data = vec![0, 1, 2, 3]; self.data.borrow() } } fn consume_iterator<'a, TIterator: Iterator<Item=&'a usize>>(iterator: TIterator) { for i in iterator { println!("{}", i); } } fn handler<'a>(ret: &'a Retriever, id: usize) -> IterWrapper<'a> { //andle_request now has a reference to the collection //So just call iter()? Nope. Lifetime issues. ret.retrieve(id).iter() } fn main() { let retriever = Retriever{data: RefCell::new(Vec::new())}; consume_iterator(handler(&retriever, 0)) }
tôi cảm thấy một chút mất ở đây và đang nhìn cái gì đó rõ ràng.
Tôi nghĩ bạn cần ['std :: vec :: IntoIter'] (https://doc.rust-lang.org/stable/std/vec/struct.IntoIter.html): https: // play. rust-lang.org/?gist=0e6c171c08fc7a314c44ac98f3dd398e&version=stable&backtrace=0 Nhưng sau đó bạn cũng có thể sử dụng trực tiếp 'IntoIter'. – Dogbert
Trong khi đó sẽ biên dịch, 'IntoIter' di chuyển các giá trị. Đầu nhận của 'Iterator' dự kiến tham chiếu đến các giá trị. Tôi sẽ cập nhật câu hỏi của tôi cho phù hợp – JDemler
Tôi sợ bạn đã bằng cách nào đó chạy vào [Vấn đề XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) ... Tại sao Bạn có cần tham chiếu đến các giá trị, nếu bạn không cần các giá trị sau đó? Toàn bộ điểm vay là vì vậy bạn giữ quyền sở hữu, nhưng dường như bạn không muốn giữ quyền sở hữu. –