Ich habe Sammlungen auf der Festplatte abgelegt. Wenn angefordert, sollten diese Sammlungen abgerufen werden (kein Problem), und es sollte eine iterator
erstellt werden, die Verweise auf die abgerufenen Werte zurückgibt. Nachdem die iterator
gelöscht wurde, brauche ich die Sammlung nicht mehr. Ich möchte, dass es auch fallen gelassen wird.Iterate über Sammlung. Lassen Sie es fallen, sobald der Iterator gelöscht wird
Was ich bisher versucht:
Die
Iterator
besitzt die Sammlung. Das hat für mich am meisten Sinn gemacht, aber es ist nicht möglich; Ich bin mir nicht ganz sicher warum. Einige sagen, dass dieIterator
Traits 'Methodensignatur fürnext
das Problem ist. (example)Referenzzählung: Die
Retriever
gibt eineRc<Vec<usize>>
zurück. Ich stieß auf die gleichen Probleme wie im besitzenden Iterator. (example)Den Retriever die Sammlung besitzen lassen und eine Referenz darauf verteilen. Ich habe versucht, den Retriever mit Interior-Mutabilität zu implementieren (
RefCell<HashMap>
), aber ich kann keine Referenzen in dieHashMap
mit ausreichend langen Lebenszeiten zurückgeben.
Ich sehe zwei grundlegende Möglichkeiten mit diesem.
Der Besitz Retriever Transfers. Dann müsste die
Iterator
die Daten besitzen. Etwas in den Zeilen: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)) }
Der Retriever besitzt die Sammlung. Aber dann treten zwei neue Probleme auf:
- Wie kann ich die Daten löschen, wenn der Iterator außer Reichweite ist?
- Wie sage ich dem Borrow-Checker, dass ich die Sammlung lange genug besitzen werde?
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)) }
Ich fühle mich hier verloren Bit und offensichtlich etwas bin mit Blick auf.
Ich denke, Sie brauchen ['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 Aber dann könnte man auch direkt 'IntoIter' verwenden. – Dogbert
Während dies kompiliert wird, verschiebt 'IntoIter' die Werte. Das empfangende Ende des 'Iterators' erwartet Verweise auf die Werte. Ich werde meine Frage entsprechend aktualisieren – JDemler
Ich fürchte, Sie haben irgendwie in das [XY Problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) gerannt ... Warum Benötigen Sie Verweise auf die Werte, wenn Sie die Werte danach nicht benötigen? Der ganze Punkt der Kreditaufnahme ist so, dass Sie den Besitz behalten, aber anscheinend wollen Sie nicht den Besitz behalten. –