Beginners Cheatsheet

Traits

Display

Wie lassen sich Structs als String darstellen?

  • Python def __str__()
  • Java public String toString()
  • Rust trait Display
#![allow(unused)]
fn main() {
pub trait Display {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>;
}
}

Beispiel:

#![allow(unused)]
fn main() {
struct ID(u32);
impl Display for ID {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[test]
fn test_display() {
    let id = ID(123);
    let s = format!("{id}");
    assert_eq!(s, "ID(123)");
    assert_eq!(id.to_string(), "ID(123)");
}
}

Docs

From & Into

Wie lassen sich Typen value-to-value konvertieren?

  • Java constructor overloading
  • Rust trait From
#![allow(unused)]
fn main() {
pub trait From<T>: Sized {
    fn from(value: T) -> Self;
}
}

Beispiel:

#![allow(unused)]
fn main() {
struct ID(u32);
impl From<u16> for ID {
    fn from(value: u16) -> Self {
        Self(value as u32)
    }
}

#[test]
fn test_from() {
    let id = ID::from(123);
    assert_eq!(id.0, ID(123).0);
    let id: ID = 123.into();
    assert_eq!(id.0, ID(123).0);
}
}

From implementiert auch den Into-Trait mit, dieser ermoeglicht den .into()-Call From darf nicht fehlschlagen, dafuer existiert der TryFrom-Trait, z. B. kann man diesen gut fuer Konvertierung von Strings in eigene Typen verwenden, um bei Fehlerhaften Strings ein Result zurueck zu geben.

Docs

Deref

#![allow(unused)]
fn main() {
pub trait Deref {
  // Ergebnis-Typ nach dereferenzierung
  type Target: ?Sized;
  fn deref(&self) -> &Self::Target;
}

#[test]
fn test_deref() {
  let id = ID(123);
  assert_eq!(123, *id);
}
}

Beispiel:

#![allow(unused)]
fn main() {
struct ID(u32);
impl<T> Deref for DerefExample<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.value
    }
}
}

Docs

Default

Wie kann man einem Typen default Werte geben?

  • Python __init__(self, id=123, username="foo")
  • Rust trait Default
#![allow(unused)]
fn main() {
pub trait Default: Sized {
    // Required method
    fn default() -> Self;
}
}

Beispiel:

#![allow(unused)]
fn main() {
struct ID(u32);
impl Default for ID {
    fn default() -> Self {
        Self(0)
    }
}
}

Beispiel mit Enum:

#![allow(unused)]
fn main() {
enum Command {
    Help,
    Run,
    Build,
}

impl Default for Command {
    fn default() -> Self { Command::Help }
}
}

Docs

Iterator

Wie mache ich eigene Typen iterierbar?

  • Python def __next__(self)
  • Java implements Iterable<T>
  • Rust trait Iterator

Beispiel

#![allow(unused)]
fn main() {
struct IDS(Vec<u32>);

impl Iterator for IDS {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.pop()
    }
}

#[test]
fn test_iterator() {
    let mut ids = IDS(vec![1, 2, 3]);
    assert_eq!(ids.next(), Some(1));
    assert_eq!(ids.next(), Some(2));
    assert_eq!(ids.next(), Some(3));
}
}

Docs

Smart Pointer

Box

Rc & Arc

RefCell: Ref & RefMut

Funktionen

Function Pointers

Closures

FnOnce, FnMut, Fn