Sized în Rust

Trait marker pentru tipurile cu dimensiune cunoscută la compilare; ?Sized permite și str, [T], dyn Trait.

Sintaxă
fn f<T>(x: &T)            // implicit T: Sized
fn f<T: ?Sized>(x: &T)    // acceptă și str, [T], dyn Trait

Ce face Sized

Aproape toate tipurile au o dimensiune fixă, cunoscută la compilare (i32 are 4 octeți, String 24 pe un sistem de 64 de biți). Ele sunt Sized, automat. Excepțiile sunt tipurile „fără dimensiune”: str, felii [T] și dyn Trait. Pe acestea le folosești mereu printr-un pointer: &str, Box<[T]>, &dyn Display.

Orice parametru generic T are implicit condiția T: Sized. Dacă funcția primește doar &T și vrei să accepte și str sau dyn Trait, relaxezi condiția cu T: ?Sized („poate fi și fără dimensiune”). Biblioteca standard face asta peste tot: impl<T: Display + ?Sized> ToString for T.

Ce returnează

Nu are metode.

Exemple

Exemplul 1: Dimensiuni: tipuri Sized și pointeri spre tipuri fără dimensiune

use std::mem::size_of;

fn main() {
    println!("i32:          {}", size_of::<i32>());
    println!("String:       {}", size_of::<String>());
    println!("&str:         {}", size_of::<&str>());       // pointer + lungime
    println!("&[u8]:        {}", size_of::<&[u8]>());
    println!("&dyn Display: {}", size_of::<&dyn std::fmt::Display>());   // pointer + tabel
    println!("&i32:         {}", size_of::<&i32>());
}

Rezultat

i32:          4
String:       24
&str:         16
&[u8]:        16
&dyn Display: 16
&i32:         8

Exemplul 2: ?Sized pentru o funcție mai generală

use std::fmt::Display;

fn afiseaza_incadrat<T: Display + ?Sized>(x: &T) {
    let text = x.to_string();
    let linie = "-".repeat(text.chars().count() + 4);
    println!("{linie}\n| {text} |\n{linie}");
}

fn main() {
    afiseaza_incadrat("Iași");            // T = str, fără dimensiune
    afiseaza_incadrat(&2026);             // T = i32
    let d: &dyn Display = &'ș';
    afiseaza_incadrat(d);                 // T = dyn Display
}

Rezultat

--------
| Iași |
--------
--------
| 2026 |
--------
-----
| ș |
-----

Greșeli frecvente

  • Scrii fn f<T: Display>(x: &T) și apelezi cu un &str: the size for values of type `str` cannot be known at compilation time. Adaugă ?Sized.
  • Încerci să ții un str sau un dyn Trait direct într-o variabilă sau un câmp. Folosește &str/String, respectiv Box<dyn Trait>.

Comenzi înrudite

  • str: Tipul pentru o bucată de text UTF-8 împrumutată (&str): literalii, părți din String, parametrii de funcții.
  • Send și Sync: Trait-uri marker automate prin care compilatorul previne erorile de concurență: Send = poate trece în alt fir, Sync = poate fi împărțit.
  • Any: Trait-ul care permite aflarea tipului concret la rulare: downcast_ref::<T>() pe &dyn Any sau Box<dyn Any>.
  • Copy: Trait marker pentru tipurile copiate automat bit cu bit la atribuire, în loc să fie mutate (numere, char, bool…).