Compartir a través de


Opciones

El tipo de opción de F# se usa cuando es posible que un valor real no exista para un valor con nombre o una variable. Una opción tiene un tipo subyacente y puede contener un valor de ese tipo o podría no tener un valor.

Observaciones

En el código siguiente se muestra una función que genera un tipo de opción.

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

Como puede ver, si el a de entrada es mayor que 0, se genera Some(a). De lo contrario, se genera None.

El valor None se usa cuando una opción no tiene un valor real. De lo contrario, la expresión Some( ... ) proporciona un valor a la opción . Los valores Some y None son útiles en la coincidencia de patrones, como en la función siguiente exists, que devuelve true si la opción tiene un valor y false si no lo hace.

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

Uso de opciones

Las opciones se suelen usar cuando una búsqueda no devuelve un resultado coincidente, como se muestra en el código siguiente.

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 ]

En el código anterior, se busca una lista de forma recursiva. La función tryFindMatch toma una función de predicado pred que devuelve un valor booleano y una lista para buscar. Si se encuentra un elemento que satisface el predicado, la recursividad finaliza y la función devuelve el valor como una opción en la expresión Some(head). La recursividad finaliza cuando se coincide con la lista vacía. En ese momento no se encontró el valor head y se devuelve None.

Muchas funciones de biblioteca de F# que buscan una colección para un valor que puede o no existir devuelven el tipo de option. Por convención, estas funciones comienzan con el prefijo try, por ejemplo, Seq.tryFindIndex.

Las opciones también pueden ser útiles cuando es posible que un valor no exista, por ejemplo, si es posible que se produzca una excepción al intentar construir un valor. En el ejemplo de código siguiente se muestra esto.

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 función openFile del ejemplo anterior tiene string -> File option de tipo porque devuelve un objeto File si el archivo se abre correctamente y None si se produce una excepción. En función de la situación, puede que no sea una opción de diseño adecuada para detectar una excepción en lugar de permitir que se propague.

Además, todavía es posible pasar null o un valor que sea NULL al Some caso de una opción. Esto suele evitarse y normalmente está en programación de F# rutinaria, pero es posible debido a la naturaleza de los tipos de referencia en .NET.

Propiedades y métodos de opción

El tipo de opción admite las siguientes propiedades y métodos.

Propiedad o método Tipo Descripción
None 'T option Miembro estático que crea un valor de opción que tiene el valor de None.
IsNone bool Devuelve true si la opción tiene el valor None.
IsSome bool Devuelve true si la opción tiene un valor que no es None.
Some 'T option Miembro estático que crea una opción que tiene un valor que no es None.
Valor 'T Devuelve el valor subyacente o produce un System.NullReferenceException si el valor es None.

Módulo opcional

Hay un módulo, Option, que contiene funciones útiles que realizan operaciones en opciones. Algunas funciones repiten la funcionalidad de las propiedades, pero son útiles en contextos en los que se necesita una función. Option.isSome y Option.isNone son funciones de módulo que prueban si una opción contiene un valor. Option.get obtiene el valor, si hay uno. Si no hay ningún valor, inicia System.ArgumentException.

La función Option.bind ejecuta una función en el valor, si hay un valor. La función debe tomar exactamente un argumento y su tipo de parámetro debe ser el tipo de opción. El valor devuelto de la función es otro tipo de opción.

El módulo de opciones también incluye funciones que corresponden a las funciones que están disponibles para listas, matrices, secuencias y otros tipos de colección. Estas funciones incluyen Option.map, Option.iter, Option.forall, Option.exists, Option.foldBack, Option.foldy Option.count. Estas funciones permiten usar opciones como una colección de uno o cero elementos. Para obtener más información y ejemplos, vea la explicación de las funciones de colección en Listas.

Conversión a otros tipos

Las opciones se pueden convertir en listas o matrices. Cuando se convierte una opción en cualquiera de estas estructuras de datos, la estructura de datos resultante tiene cero o un elemento. Para convertir una opción en una matriz, use Option.toArray. Para convertir una opción en una lista, use Option.toList.

Conversión de opciones con valores predeterminados

Además de convertir en listas y matrices, las opciones se pueden convertir a otros tipos proporcionando valores predeterminados mediante la función Option.defaultValue. Esto resulta especialmente útil cuando desea asegurarse de que el valor no es None. Por ejemplo:

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 función Option.defaultValue permite manejar sin problemas tanto los casos Some como None sin coincidencias de patrones.

Consulte también