Chciałbym zrobić iterator, który generuje strumień liczb pierwszych. Mój ogólny proces myślowy było owinąć iterator z kolejnych filtrów tak na przykład zacząćJak komponować zmienne Iteratory?
let mut n = (2..N)
Następnie dla każdej liczby pierwszej ty zmutować iterator i dodać na filtrze
let p1 = n.next()
n = n.filter(|&x| x%p1 !=0)
let p2 = n.next()
n = n.filter(|&x| x%p2 !=0)
próbuję należy użyć następującego kodu, ale nie wydaje się uzyskać go do pracy
struct Primes {
base: Iterator<Item = u64>,
}
impl<'a> Iterator for Primes<'a> {
type Item = u64;
fn next(&mut self) -> Option<u64> {
let p = self.base.next();
match p {
Some(n) => {
let prime = n.clone();
let step = self.base.filter(move |&: &x| {x%prime!=0});
self.base = &step as &Iterator<Item = u64>;
Some(n)
},
_ => None
}
}
}
mam bawił się z odmian tego, ale nie wydaje się uzyskać wcieleń i typów, aby dopasować się. Teraz kompilator mówi mi
- Nie mogę mutować self.base
- zmienna prime nie żyje wystarczająco długo
Tutaj jest błąd otrzymuję
solution.rs:16:17: 16:26 error: cannot borrow immutable borrowed content `*self.base` as mutable
solution.rs:16 let p = self.base.next();
^~~~~~~~~
solution.rs:20:28: 20:37 error: cannot borrow immutable borrowed content `*self.base` as mutable
solution.rs:20 let step = self.base.filter(move |&: &x| {x%prime!=0});
^~~~~~~~~
solution.rs:21:30: 21:34 error: `step` does not live long enough
solution.rs:21 self.base = &step as &Iterator<Item = u64>;
^~~~
solution.rs:15:39: 26:6 note: reference must be valid for the lifetime 'a as defined on the block at 15:38...
solution.rs:15 fn next(&mut self) -> Option<u64> {
solution.rs:16 let p = self.base.next();
solution.rs:17 match p {
solution.rs:18 Some(n) => {
solution.rs:19 let prime = n.clone();
solution.rs:20 let step = self.base.filter(move |&: &x| {x%prime!=0});
...
solution.rs:20:71: 23:14 note: ...but borrowed value is only valid for the block suffix following statement 1 at 20:70
solution.rs:20 let step = self.base.filter(move |&: &x| {x%prime!=0});
solution.rs:21 self.base = &step as &Iterator<Item = u64>;
solution.rs:22 Some(n)
solution.rs:23 },
error: aborting due to 3 previous errors
Dlaczego Rust nie pozwala mi tego zrobić?
No cóż, ja całkowicie zapomniałem o tym. Dzięki! –
* i przy obiektach referencji referencyjnych nie można ich nigdzie przechować * - dodatkowo, rzeczywisty ** rozmiar ** iteratora 'base' zmienia się wraz z coraz większym zagnieżdżaniem. Dlatego musimy użyć alokacji sterty, aby wielkość 'Primes' była zawsze stała. – Shepmaster
@Shepmaster, Rozmiar obiektu referencyjnego cechy nie zmienia się, afaik. Jedynym powodem, dla którego nie można go wykorzystać, jest własność. –