F # - Generici

I generici consentono di ritardare la specifica del tipo di dati degli elementi di programmazione in una classe o in un metodo, fino a quando non viene effettivamente utilizzato nel programma. In altre parole, i generici ti consentono di scrivere una classe o un metodo che può funzionare con qualsiasi tipo di dati.

Scrivi le specifiche per la classe o il metodo, con parametri sostitutivi per i tipi di dati. Quando il compilatore incontra un costruttore per la classe o una chiamata di funzione per il metodo, genera codice per gestire il tipo di dati specifico.

In F #, i valori di funzione, i metodi, le proprietà e i tipi di aggregazione come classi, record e unioni discriminate possono essere generici.

I costrutti generici contengono almeno un parametro di tipo. Funzioni e tipi generici consentono di scrivere codice che funziona con una varietà di tipi senza ripetere il codice per ogni tipo.

Sintassi

La sintassi per scrivere un costrutto generico è la seguente:

// Explicitly generic function.
let function-name<type-parameters> parameter-list =
   function-body

// Explicitly generic method.
[ static ] member object-identifer.method-name<type-parameters> parameter-list [ return-type ] =
   method-body

// Explicitly generic class, record, interface, structure,
// or discriminated union.
type type-name<type-parameters> type-definition

Esempi

(* Generic Function *)
let printFunc<'T> x y =
   printfn "%A, %A" x y

printFunc<float> 10.0 20.0

Quando compili ed esegui il programma, restituisce il seguente output:

10.0, 20.0

È inoltre possibile rendere generica una funzione utilizzando la sintassi delle virgolette singole:

(* Generic Function *)
let printFunction (x: 'a) (y: 'a) =
   printfn "%A %A" x y

printFunction 10.0 20.0

Quando compili ed esegui il programma, restituisce il seguente output:

10.0 20.0

Si noti che quando si utilizzano funzioni o metodi generici, potrebbe non essere necessario specificare gli argomenti del tipo. Tuttavia, in caso di ambiguità, è possibile fornire argomenti di tipo tra parentesi angolari come abbiamo fatto nel primo esempio.

Se hai più di un tipo, separa più argomenti di tipo con virgole.

Classe generica

Come le funzioni generiche, puoi anche scrivere classi generiche. Il seguente esempio lo dimostra:

type genericClass<'a> (x: 'a) =
   do printfn "%A" x

let gr = new genericClass<string>("zara")
let gs = genericClass( seq { for i in 1 .. 10 -> (i, i*i) } )

Quando compili ed esegui il programma, restituisce il seguente output:

"zara"
seq [(1, 1); (2, 4); (3, 9); (4, 16); ...]