Partager via


Options

Le type d’option en F# est utilisé lorsqu’une valeur réelle n’existe peut-être pas pour une valeur nommée ou une variable. Une option a un type sous-jacent et peut contenir une valeur de ce type, ou elle n’a peut-être pas de valeur.

Remarques

Le code suivant illustre une fonction qui génère un type d’option.

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

Comme vous pouvez le voir, si la a d’entrée est supérieure à 0, Some(a) est générée. Sinon, None est généré.

La valeur None est utilisée lorsqu’une option n’a pas de valeur réelle. Sinon, l’expression Some( ... ) donne à l’option une valeur. Les valeurs Some et None sont utiles dans la mise en correspondance des modèles, comme dans la fonction suivante exists, qui retourne true si l’option a une valeur et false si ce n’est pas le cas.

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

Utilisation des options

Les options sont couramment utilisées lorsqu’une recherche ne retourne pas de résultat correspondant, comme indiqué dans le code suivant.

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 ]

Dans le code précédent, une liste est recherchée de manière récursive. La fonction tryFindMatch prend une fonction de prédicat pred qui retourne une valeur booléenne et une liste à rechercher. Si un élément qui satisfait le prédicat est trouvé, la récursivité se termine et la fonction retourne la valeur en tant qu’option dans l’expression Some(head). La récursivité se termine lorsque la liste vide est trouvée. À ce stade, la valeur head n’a pas été trouvée et None est retournée.

De nombreuses fonctions de bibliothèque F# qui recherchent une collection pour une valeur susceptible ou non d’exister retournent le type option. Par convention, ces fonctions commencent par le préfixe try, par exemple, Seq.tryFindIndex.

Les options peuvent également être utiles lorsqu’une valeur n’existe pas, par exemple s’il est possible qu’une exception soit levée lorsque vous essayez de construire une valeur. L’exemple de code suivant illustre cela.

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 fonction openFile dans l’exemple précédent a un type string -> File option car elle retourne un objet File si le fichier s’ouvre correctement et None si une exception se produit. Selon la situation, il peut ne pas s’agir d’un choix de conception approprié pour intercepter une exception plutôt que de l’autoriser à se propager.

De plus, il est toujours possible de passer null ou une valeur nulle au cas Some d'une option. Cela est généralement à éviter, et généralement dans la programmation F# de routine, mais est possible en raison de la nature des types de référence dans .NET.

Propriétés et méthodes des options

Le type d’option prend en charge les propriétés et méthodes suivantes.

Propriété ou méthode Type Description
None 'T option Membre statique qui crée une valeur d’option qui a la valeur None.
IsNone bool Retourne true si l’option a la valeur None.
IsSome bool Retourne true si l’option a une valeur qui n’est pas None.
Some 'T option Membre statique qui crée une option qui a une valeur qui n’est pas None.
Valeur 'T Retourne la valeur sous-jacente ou génère une exception System.NullReferenceException si la valeur est None.

Module d’option

Il existe un module, Option, qui contient des fonctions utiles qui effectuent des opérations sur les options. Certaines fonctions répètent les fonctionnalités des propriétés, mais sont utiles dans les contextes où une fonction est nécessaire. Option.isSome et Option.isNone sont les deux fonctions de module qui testent si une option contient une valeur. Option.get obtient la valeur, s'il y en a une. S’il n’existe aucune valeur, il génère System.ArgumentException.

La fonction Option.bind exécute une fonction sur la valeur, s’il existe une valeur. La fonction doit prendre exactement un argument, et son type de paramètre doit être le type d’option. La valeur de retour de la fonction est un autre type d’option.

Le module d’option inclut également des fonctions qui correspondent aux fonctions disponibles pour les listes, les tableaux, les séquences et d’autres types de collection. Ces fonctions incluent Option.map, Option.iter, Option.forall, Option.exists, Option.foldBack, Option.foldet Option.count. Ces fonctions permettent d’utiliser des options comme une collection de zéro ou d'un seul élément. Pour plus d’informations et d’exemples, consultez la discussion sur les fonctions de collection dans Lists.

Conversion vers d'autres types

Les options peuvent être converties en listes ou tableaux. Lorsqu’une option est convertie en l’une de ces structures de données, la structure de données résultante a zéro ou un élément. Pour convertir une option en tableau, utilisez Option.toArray. Pour convertir une option en liste, utilisez Option.toList.

Conversion d’options avec des valeurs par défaut

Outre la conversion en listes et tableaux, les options peuvent être converties en d’autres types en fournissant des valeurs par défaut à l’aide de la fonction Option.defaultValue. Cela est particulièrement utile lorsque vous souhaitez vous assurer que la valeur n’est pas None. Par exemple:

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 fonction Option.defaultValue vous permet de gérer les cas Some et None en toute transparence sans correspondance de modèle.

Voir aussi