Partilhar via


Opções

O tipo de opção em F# é usado quando um valor real pode não existir para um valor nomeado ou variável. Uma opção tem um tipo subjacente e pode conter um valor desse tipo, ou pode não ter um valor.

Observações

O código a seguir ilustra uma função que gera um tipo de opção.

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

Como você pode ver, se a entrada a for maior que 0, Some(a) é gerada. Caso contrário, None é gerado.

O valor None é usado quando uma opção não tem um valor real. Caso contrário, a expressão Some( ... ) dá um valor à opção. Os valores Some e None são úteis na correspondência de padrões, como na função existsa seguir, que retorna true se a opção tiver um valor e false se não tiver.

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

Usando opções

As opções são normalmente usadas quando uma pesquisa não retorna um resultado correspondente, conforme mostrado no código a seguir.

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 ]

No código anterior, uma lista é pesquisada recursivamente. A função tryFindMatch usa uma função pred de predicado que retorna um valor booleano e uma lista para pesquisar. Se um elemento que satisfaz o predicado for encontrado, a recursão termina e a função retorna o valor como uma opção na expressão Some(head). A recursão termina quando a lista vazia é correspondida. Nesse ponto, o valor head não foi encontrado e None é retornado.

Muitas funções de biblioteca F# que pesquisam uma coleção por um valor que pode ou não existir retornam o option tipo. Por convenção, essas funções começam com o prefixo try , por exemplo, Seq.tryFindIndex.

As opções também podem ser úteis quando um valor pode não existir, por exemplo, se for possível que uma exceção seja lançada quando você tenta construir um valor. O exemplo de código a seguir ilustra isso.

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

A openFile função no exemplo anterior tem tipo string -> File option porque retorna um File objeto se o arquivo for aberto com êxito e None se ocorrer uma exceção. Dependendo da situação, pode não ser uma escolha de design apropriada capturar uma exceção em vez de permitir que ela se propague.

Além disso, ainda é possível passar null ou um valor que é nulo para o Some caso de uma opção. Isso geralmente deve ser evitado, e normalmente está na programação F# de rotina, mas é possível devido à natureza dos tipos de referência no .NET.

Propriedades e métodos da opção

O tipo de opção suporta as seguintes propriedades e métodos.

Propriedade ou método Tipo Description
None 'T option Um membro estático que cria um valor de opção que tem o None valor.
IsNone bool Devolve true se a opção tiver o None valor.
IsSome bool Retorna true se a opção tiver um valor que não Noneé .
Some 'T option Um membro estático que cria uma opção que tem um valor que não Noneé .
Valor 'T Devolve o valor subjacente ou lança um System.NullReferenceException se o valor for None.

Módulo de opção

Há um módulo, Option, que contém funções úteis que executam operações em opções. Algumas funções repetem a funcionalidade das propriedades, mas são úteis em contextos onde uma função é necessária. Option.isSome e Option.isNone são funções de módulo que testam se uma opção mantém um valor. Option.get obtém o valor, se houver. Se não houver valor, lança.System.ArgumentException

A função Option.bind executa uma função no valor, se houver um valor. A função deve ter exatamente um argumento, e seu tipo de parâmetro deve ser o tipo de opção. O valor de retorno da função é outro tipo de opção.

O módulo de opção também inclui funções que correspondem às funções disponíveis para listas, matrizes, sequências e outros tipos de coleção. Essas funções incluem Option.map, Option.iter, Option.forall, Option.exists, Option.foldBack, Option.folde Option.count. Essas funções permitem que as opções sejam usadas como uma coleção de zero ou um elemento. Para obter mais informações e exemplos, consulte a discussão sobre funções de coleta em Listas.

Convertendo para outros tipos

As opções podem ser convertidas em listas ou matrizes. Quando uma opção é convertida em qualquer uma dessas estruturas de dados, a estrutura de dados resultante tem zero ou um elemento. Para converter uma opção em uma matriz, use Option.toArray. Para converter uma opção em uma lista, use Option.toList.

Consulte também