Condividi tramite


Opzioni

Il tipo di opzione in F# viene usato quando un valore effettivo potrebbe non esistere per un valore o una variabile denominata. Un'opzione ha un tipo sottostante e può contenere un valore di tale tipo oppure potrebbe non avere un valore.

Osservazioni

Il codice seguente illustra una funzione che genera un tipo di opzione.

let keepIfPositive (a: int) = if a > 0 then Some(a) else None

Come si può notare, se il a di input è maggiore di 0, viene generato Some(a). In caso contrario, None viene generato.

Il valore None viene usato quando un'opzione non ha un valore effettivo. In caso contrario, l'espressione Some( ... ) assegna all'opzione un valore. I valori Some e None sono utili per i criteri di ricerca, come nella funzione seguente exists, che restituisce true se l'opzione ha un valore e false in caso contrario.

let exists (x: int option) =
    match x with
    | Some(x) -> true
    | None -> false

Uso delle opzioni

Le opzioni vengono comunemente usate quando una ricerca non restituisce un risultato corrispondente, come illustrato nel codice seguente.

let rec tryFindMatch pred list =
    match list with
    | head :: tail -> if pred (head) then Some(head) else tryFindMatch pred tail
    | [] -> None

// result1 is Some 100 and its type is int option.
let result1 = tryFindMatch (fun elem -> elem = 100) [ 200; 100; 50; 25 ]

// result2 is None and its type is int option.
let result2 = tryFindMatch (fun elem -> elem = 26) [ 200; 100; 50; 25 ]

Nel codice precedente viene eseguita una ricerca ricorsiva in un elenco. La funzione tryFindMatch accetta una funzione predicato pred che restituisce un valore booleano e un elenco da cercare. Se viene trovato un elemento che soddisfa il predicato, la ricorsione termina e la funzione restituisce il valore come opzione nell'espressione Some(head). La ricorsione termina quando viene trovata una corrispondenza con l'elenco vuoto. A questo punto il valore head non è stato trovato e None viene restituito.

Molte funzioni esistenti della libreria F# che cercano un valore in una collezione che potrebbe esistere oppure no ritornano il tipo option. Per convenzione, queste funzioni iniziano con il prefisso try, ad esempio Seq.tryFindIndex.

Le opzioni possono essere utili anche quando un valore potrebbe non esistere, ad esempio se è possibile che venga generata un'eccezione quando si tenta di costruire un valore. Nell'esempio di codice seguente viene illustrato questo.

open System.IO

let openFile filename =
    try
        let file = File.Open(filename, FileMode.Create)
        Some(file)
    with ex ->
        eprintf "An exception occurred with message %s" ex.Message
        None

La funzione openFile nell'esempio precedente ha un tipo string -> File option perché restituisce un oggetto File se il file viene aperto correttamente e None se si verifica un'eccezione. A seconda della situazione, potrebbe non essere una scelta di progettazione appropriata per intercettare un'eccezione anziché consentire la propagazione.

Inoltre, è comunque possibile passare null o un valore null al caso Some di un'opzione. Questo è in genere da evitare e in genere si trova nella programmazione F# di routine, ma è possibile a causa della natura dei tipi di riferimento in .NET.

Proprietà e metodi delle opzioni

Il tipo di opzione supporta le proprietà e i metodi seguenti.

Proprietà o metodo Digitare Descrizione
None 'T option Membro statico che crea un valore di opzione con il valore None.
IsNone bool Restituisce true se l'opzione ha il valore None.
IsSome bool Restituisce true se l'opzione ha un valore che non è None.
Some 'T option Membro statico che crea un'opzione con un valore che non è None.
valore 'T Restituisce il valore sottostante o genera un System.NullReferenceException se il valore è None.

Modulo di opzione

È disponibile un modulo, Option, che contiene funzioni utili che eseguono operazioni sulle opzioni. Alcune funzioni ripetono la funzionalità delle proprietà, ma sono utili nei contesti in cui è necessaria una funzione. Option.isSome e Option.isNone sono entrambe funzioni del modulo che verificano se un'opzione contiene un valore. Option.get ottiene il valore, se esiste. Se non è presente alcun valore, genera System.ArgumentException.

La funzione Option.bind esegue una funzione sul valore, se è presente un valore. La funzione deve accettare esattamente un argomento e il tipo di parametro deve essere il tipo di opzione. Il valore restituito della funzione è un altro tipo di opzione.

Il modulo di opzione include anche funzioni che corrispondono alle funzioni disponibili per elenchi, matrici, sequenze e altri tipi di raccolta. Queste funzioni includono Option.map, Option.iter, Option.forall, Option.exists, Option.foldBack, Option.folde Option.count. Queste funzioni consentono di usare le opzioni come una raccolta di zero o uno elementi. Per altre informazioni ed esempi, vedere la discussione sulle funzioni di raccolta in Elenchi.

Conversione ad altri tipi

Le opzioni possono essere convertite in elenchi o matrici. Quando un'opzione viene convertita in una di queste strutture di dati, la struttura di dati risultante ha zero o un elemento. Per convertire un'opzione in una matrice, usare Option.toArray. Per convertire un'opzione in un elenco, usare Option.toList.

Conversione di opzioni con valori predefiniti

Oltre alla conversione in elenchi e matrici, le opzioni possono essere convertite in altri tipi fornendo valori predefiniti usando la funzione Option.defaultValue. Ciò è particolarmente utile quando si vuole assicurarsi che il valore non sia None. Per esempio:

let optionString = Some("F#")
let defaultString = optionString |> Option.defaultValue ""
// defaultString is "F#"

let optionInt = None
let defaultInt = optionInt |> Option.defaultValue 0
// defaultInt is 0

La funzione Option.defaultValue consente di gestire i casi di Some e None senza corrispondenza dei pattern.

Vedere anche