EMZETT.
Login

Kurz: let mut leer: Vec<String> = Vec::new(); leer.push(“a”.to_string()); let mit_kapazitaet: Vec<u8> = Vec::with_capacity(100); println!(”{} {}”, leer.len(), mit_kapazitaet.capacity() >= 100);

Teil des Kurses Rust

Kapitel 8 von 13 im Kurs Rust (Abschnitt „Standardbibliothek“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Vec: die wachsende Liste

fn main() {
    let mut v = vec![5, 3, 9];
    v.push(1);
    v.insert(1, 42);
    println!("{v:?} {} {:?} {:?}", v.len(), v.first(), v.get(10));
    println!("{} {}", v[0], v.contains(&9));
    let letztes = v.pop();
    v.remove(0);
    println!("{letztes:?} {v:?}");
    v.sort();
    v.reverse();
    println!("{v:?}");
    v.extend([7, 8]);
    v.retain(|&x| x != 8);
    v.dedup();
    println!("{v:?} {:?} {:?}", v.iter().max(), v.iter().sum::<i32>());
 
    let mut leer: Vec<String> = Vec::new();
    leer.push("a".to_string());
    let mit_kapazitaet: Vec<u8> = Vec::with_capacity(100);
    println!("{} {}", leer.len(), mit_kapazitaet.capacity() >= 100);
 
    println!("{:?} {:?}", &v[1..3], v.chunks(2).collect::<Vec<_>>());
    println!("{:?}", v.windows(2).map(|w| w[1] - w[0]).collect::<Vec<_>>());
}

Ausgabe:

[5, 42, 3, 9, 1] 5 Some(5) None
5 true
Some(1) [42, 3, 9]
[42, 9, 3]
[42, 9, 3, 7] Some(42) 61
1 true
[9, 3] [[42, 9], [3, 7]]
[-33, -6, 4]

Der Zugriff v[i] löst bei falschem Index eine Panic aus; v.get(i) liefert Option<&T>.

HashMap

use std::collections::HashMap;
 
fn main() {
    let mut alter: HashMap<String, u32> = HashMap::new();
    alter.insert("Mia".to_string(), 17);
    alter.insert("Tom".to_string(), 19);
    alter.insert("Mia".to_string(), 18);                 // überschreibt
    println!("{:?} {:?} {}", alter.get("Mia"), alter.get("Zoe"), alter.len());
 
    alter.entry("Zoe".to_string()).or_insert(21);       // nur einfügen, wenn fehlt
    *alter.entry("Tom".to_string()).or_insert(0) += 1;   // ändern
    if let Some(a) = alter.get_mut("Mia") { *a += 1; }
    alter.remove("Tom");
 
    let mut namen: Vec<_> = alter.iter().collect();      // Reihenfolge ist zufällig: sortieren!
    namen.sort();
    println!("{namen:?}");
 
    let mut zaehler: HashMap<char, usize> = HashMap::new();
    for c in "mississippi".chars() {
        *zaehler.entry(c).or_insert(0) += 1;
    }
    let mut paare: Vec<_> = zaehler.into_iter().collect();
    paare.sort_by(|a, b| b.1.cmp(&a.1).then(a.0.cmp(&b.0)));
    println!("{paare:?}");
 
    let von_paaren: HashMap<&str, i32> = [("a", 1), ("b", 2)].into_iter().collect();
    println!("{}", von_paaren["b"]);
}

Ausgabe:

Some(18) None 2
[("Mia", 19), ("Zoe", 21)]
[('i', 4), ('s', 4), ('p', 2), ('m', 1)]
2

Weitere Collections

TypEigenschaft
Vec<T>wachsende Liste (Standard)
VecDeque<T>Warteschlange (vorn und hinten schnell)
HashMap<K, V>, HashSet<T>Hash-Tabellen
BTreeMap<K, V>, BTreeSet<T>sortiert
BinaryHeap<T>Prioritätswarteschlange
[T; N], &[T]Array, Slice
String, &strText
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashSet, VecDeque};
 
fn main() {
    let a: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
    let b: HashSet<i32> = [3, 4, 5].into_iter().collect();
    let mut schnitt: Vec<_> = a.intersection(&b).copied().collect();
    schnitt.sort();
    let mut vereinigung: Vec<_> = a.union(&b).copied().collect();
    vereinigung.sort();
    println!("{schnitt:?} {vereinigung:?}");
 
    let sortiert: BTreeSet<_> = [5, 1, 3, 1].into_iter().collect();
    println!("{sortiert:?}");
    let mut bm = BTreeMap::new();
    bm.insert("b", 2); bm.insert("a", 1);
    println!("{bm:?}");
 
    let mut schlange = VecDeque::new();
    schlange.push_back(1); schlange.push_back(2); schlange.push_front(0);
    println!("{:?} {:?}", schlange.pop_front(), schlange);
 
    let mut heap = BinaryHeap::from(vec![3, 8, 1]);
    heap.push(5);
    println!("{:?} {}", heap.pop(), heap.len());
}

Ausgabe:

[3, 4] [1, 2, 3, 4, 5]
{1, 3, 5}
{"a": 1, "b": 2}
Some(0) [1, 2]
Some(8) 3

Eigentum in Collections

Collections besitzen ihre Elemente. Zum Lesen leihst du dir die Elemente aus:

fn main() {
    let namen = vec![String::from("Mia"), String::from("Tom")];
    for n in &namen { print!("{n} "); }          // leiht aus: namen bleibt benutzbar
    println!();
    let laengen: Vec<usize> = namen.iter().map(|n| n.len()).collect();
    println!("{laengen:?} {}", namen.len());
    for n in namen { print!("{} ", n.to_uppercase()); }   // verbraucht namen
    println!();
    // println!("{}", namen.len());               // Fehler: namen wurde verbraucht
}

Ausgabe:

Mia Tom
[3, 3] 2
MIA TOM

Merke

  • Vec<T>: push, pop, insert, remove, sort, iter, get (sicher) vs v[i] (Panic bei Fehlindex)
  • HashMap<K, V>: insert, get, entry().or_insert(); Reihenfolge ist zufällig
  • BTreeMap/BTreeSet sind sortiert, VecDeque für Warteschlangen, BinaryHeap für Prioritäten
  • for x in &v leiht aus, for x in v verbraucht die Collection
  • Nutze .entry() für “einfügen oder ändern”

Übungsaufgabe

Zähle Wörter in einem Satz mit einer HashMap und gib die drei häufigsten sortiert aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Fehlerbehandlung mit Result

Weiter: Traits und Generics

Alle Kapitel: Rust im Überblick