Erweitern eines VecDeque zur Begrenzung der Größe
Ich möchte eine VecDeque mit einer maximalen Größenbeschränkung implementieren. Ich habe zwei Strategien, kann sie aber auch nicht abschließen.
Erster Ansatz: Vererbung durch Zusammensetzung.
Ich habe eine neue Struktur erstellt:
pub struct LimVecDeque<T> {
deque: VecDeque<T>,
limit: usize,
}
Und erstellen Sie eine neue Push-Funktion:
impl<T> LimVecDeque<T> {
...
pub fn push (&self, elem: T) {
self.deque.push_back(elem);
if self.limit < self.deque.len() {
self.deque.pop_front();
}
}
...
}
Dies funktioniert, aber wenn mein Programm erwachsen wird, muss ich meiner LimVecDeque Struct Funktionalität hinzufügen. Die meisten davon sind eine Kopie des ursprünglichen VecDeque:
pub fn len(&self) -> usize {
self.deque.len()
}
Ich habe mehr Probleme beim Exportieren von VecDeque :: iter (). Ich hatte Probleme mit Typen und Iteratoren (ich bin noch nicht sehr gut mit Iteratoren). Dieser Ansatz zwingt mich, jede Funktion in VecDeque in LimVecDeque zu klonen / exportieren. Viel Arbeit!
Zweiter Ansatz: Erstellen Sie ein neues Merkmal und implementieren Sie es für VecDeque:
trait Limited {
type Elem;
pub fn push_bounded(&self, limit: usize, elem: Elem);
}
und später das Merkmal mit VecDeque implizieren.
Aber ich muss limitbei jeder Einfügung einen Wert übergeben. Wie kann der Grenzwert einmal überschritten werden?
Was ist im Allgemeinen eine einfache Möglichkeit, einer Struktur von std aus Funktionen hinzuzufügen (ohne aktuelle zu verlieren / auszublenden)?
Antworten
Wie aus der Antwort von edkeveked hervorgeht, steht eine Kiste zur Verfügung ( BoundedVecDequeue), die den genauen Fall implementiert, den Sie implementieren möchten .
Wenn Sie sich die Implementierung von BoundedVecDequeueansehen, werden Sie feststellen, dass das erste von Ihnen beschriebene Muster verwendet wird: um Wrapper-Methoden zu erstellen, bei denen das Verhalten des umschlossenen Typs geändert werden muss, und um Methodenaufrufe zu delegieren, bei denen dies nicht der Fall ist.
Wie Sie hervorheben, kann dies zu viel Kesselplatte führen. Um den Arbeitsaufwand zu verringern, können Sie die Delegatenkiste ausprobieren , die ein Makro hinzufügt, das die Delegierung für Sie übernimmt:
use delegate::delegate;
impl<T> LimVecDeque<T> {
delegate! {
to self.inner {
pub fn len(&self) -> usize;
pub fn truncate(&mut self, new_len: usize);
pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]);
// etc
}
}
// ...
}
Vorsichtsmaßnahme: Ich habe diese Kiste selbst noch nicht benutzt, daher kann ich nicht für ihre Qualität bürgen.
BoundedVecDeque macht genau das
use ::bounded_vec_deque::BoundedVecDeque;
fn main() {
let mut a = BoundedVecDeque::new(2);
a.push_front(2);
a.push_front(3);
a.push_front(4);
println!("{:?}", a); //4, 3
}