Alias di tipo

La parola-chiave type permette di dichiarare un alias di un altro tipo:

fn main() { type Nome = String; }
type Nome = String;

Si può poi usare questo tipo come se fosse un vero tipo:

fn main() { type Nome = String; let x: Nome = "Hello".to_string(); }
type Nome = String;

let x: Nome = "Hello".to_string();

Si noti, però, che questo è un alias, non un tipo interamente nuovo. In altre parole, siccome Rust è fortemente tipizzato, ci si aspetterebbe che un confronto fra due tipi diversi fallisse:

fn main() { let x: i32 = 5; let y: i64 = 5; if x == y { // ... } }
let x: i32 = 5;
let y: i64 = 5;

if x == y {
   // ...
}

questo dà

error: mismatched types:
 expected `i32`,
    found `i64`
(expected i32,
    found i64) [E0308]
     if x == y {
             ^

Ma, se avessimo un alias:

fn main() { type Num = i32; let x: i32 = 5; let y: Num = 5; if x == y { // ... } }
type Num = i32;

let x: i32 = 5;
let y: Num = 5;

if x == y {
   // ...
}

Questo compila senza errori. Il valore di tipo Num è identico in ogni aspetto al valore di tipo i32. Per ottenere un tipo veramente nuovo, si può usare una struttura ennupla.

Gli alias di tipo possono essere usati anche con i generici:

fn main() { use std::result; enum ErroreConcreto { Foo, Bar, } type Result<T> = result::Result<T, ErroreConcreto>; }
use std::result;

enum ErroreConcreto {
    Foo,
    Bar,
}

type Result<T> = result::Result<T, ErroreConcreto>;

Questo codice crea una versione specializzata del tipo Result, che ha sempre un ErroreConcreto nella parte E di Result<T, E>. Questo viene usato tipicamente nella libreria standard per creare errori personalizzati per ogni sottosezione. Per esempio, io::Result.