Guide

Common traits

The standard library has traits that almost every type wants. Rust can write many of them for you.

derive

#[derive(...)] above a struct or enum writes trait impls for you.

#[derive(Debug, Clone, PartialEq)]struct Point {    x: i32,    y: i32,}

It works only if every field also has that trait. The attribute can also sit on the same line as the struct: #[derive(Debug)] struct Id(u32);.

PartialEq

PartialEq makes == and != work. A derived PartialEq compares every field. Without it, a == b fails with E0369. You can also write it by hand: implement fn eq(&self, other: &Self) -> bool.

let a = Point { x: 1, y: 2 };let b = Point { x: 1, y: 2 };println!("{}", a == b); // true

Display

Display controls how {} prints a value. It can't be derived; you write it yourself.

use std::fmt;impl fmt::Display for Point {    fn fmt(&self, f: &mut fmt::Formatter)        -> fmt::Result {        write!(f, "({}, {})", self.x, self.y)    }}

use std::fmt; lets you write the short names fmt::Display and fmt::Formatter. write! works like println!, but writes into f. Once you have Display, to_string() works too.

Default

Default gives a starting value with Type::default(). A derived Default uses each field's default: 0 for numbers, false for bool, and an empty String.

#[derive(Default)]struct Config { level: u8, name: String }let c = Config::default(); // level 0, name ""

Clone vs Copy

  • Clone gives you .clone(), which you call yourself.
  • Copy makes plain assignment copy the value instead of moving it.
  • Copy needs Clone too, and every field must be Copy.
  • A struct with a String can be Clone but never Copy (E0204).

Remember

  • derive writes standard impls when every field supports them.
  • == needs PartialEq; {} needs Display.
  • Default gives zero-like starting values.
  • Clone is explicit; Copy happens on every assignment.