Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tópico descreve como o valor nulo é usado em F#.
Valores nulos antes de F# 9
O valor nulo normalmente não é usado em F# para valores ou variáveis. No entanto, nulo aparece como um valor anormal em determinadas situações. Se um tipo for definido em F#, nulo não será permitido como um valor regular, a menos que o atributo AllowNullLiteral seja aplicado ao tipo. Se um tipo for definido em alguma outra linguagem .NET, nulo será um valor possível e, quando você estiver interoperando com esses tipos, seu código F# poderá encontrar valores nulos.
Para um tipo definido no F# e usado estritamente de F#, a única maneira de criar um valor nulo usando a biblioteca F# diretamente é usar Unchecked.defaultof ou Array.zeroCreate. No entanto, para um tipo F# usado de outras linguagens .NET ou se você estiver usando esse tipo com uma API que não é escrita em F#, como o .NET Framework, valores nulos podem ocorrer.
Você pode usar o tipo option em F# quando você pode usar uma variável de referência com um possível valor nulo em outra linguagem .NET. Em vez de nulo, com um tipo option F#, use o valor None da opção se não houver nenhum objeto. Você usa o valor Some(obj) da opção com um objeto obj quando há um objeto. Para obter mais informações, veja Opções. Observe que você ainda pode empacotar um valor null em uma Opção se, para Some x, acontecer de x ser null. Por isso, é importante que você use None quando um valor é null.
A palavra-chave null é uma palavra-chave válida em F#e você precisa usá-la quando estiver trabalhando com APIs do .NET Framework ou outras APIs escritas em outra linguagem .NET. As duas situações em que você pode precisar de um valor nulo são quando você chama uma API .NET e passa um valor nulo como um argumento e quando você interpreta o valor retornado ou um parâmetro de saída de uma chamada de método .NET.
Para passar um valor nulo para um método .NET, basta usar a palavra-chave null no código de chamada. O exemplo de código a seguir ilustra isso.
open System
// Pass a null value to a .NET method.
let ParseDateTime (str: string) =
let (success, res) =
DateTime.TryParse(str, null, System.Globalization.DateTimeStyles.AssumeUniversal)
if success then Some(res) else None
Para interpretar um valor nulo obtido de um método .NET, use a correspondência de padrões se possível. O exemplo de código a seguir mostra como usar a correspondência de padrões para interpretar o valor nulo retornado de ReadLine quando ele tenta ler após o final de um fluxo de entrada.
// Open a file and create a stream reader.
let fileStream1 =
try
System.IO.File.OpenRead("TextFile1.txt")
with :? System.IO.FileNotFoundException ->
printfn "Error: TextFile1.txt not found."
exit (1)
let streamReader = new System.IO.StreamReader(fileStream1)
// ProcessNextLine returns false when there is no more input;
// it returns true when there is more input.
let ProcessNextLine nextLine =
match nextLine with
| null -> false
| inputString ->
match ParseDateTime inputString with
| Some(date) -> printfn "%s" (date.ToLocalTime().ToString())
| None -> printfn "Failed to parse the input."
true
// A null value returned from .NET method ReadLine when there is
// no more input.
while ProcessNextLine(streamReader.ReadLine()) do
()
Os valores nulos para tipos F# também podem ser gerados de outras maneiras, como quando você usa Array.zeroCreate, que chama Unchecked.defaultof. Você deve ter cuidado com esse código para manter os valores nulos encapsulados. Em uma biblioteca destinada apenas a F#, você não precisa verificar se há valores nulos em cada função. Se você estiver escrevendo uma biblioteca para interoperação com outros idiomas do .NET, talvez seja necessário adicionar verificações para parâmetros de entrada nulos e lançar um ArgumentNullException, assim como você faz no código C# ou no Visual Basic.
Você pode usar o código a seguir para verificar se um valor arbitrário é nulo.
match box value with
| null -> printf "The value is null."
| _ -> printf "The value is not null."
Valores nulos começando com F# 9
No F# 9, recursos extras são adicionados ao idioma para lidar com tipos de referência que podem ter null como um valor. Elas estão desativadas por padrão – para ativá-las, a seguinte propriedade deve ser colocada no arquivo de projeto:
<Nullable>enable</Nullable>
Isso passa o sinalizador --checknulls+ para o compilador F# e define uma diretiva de pré-processador NULLABLE para o build.
Para optar explicitamente por anulabilidade, uma declaração de tipo precisa ser sufixada com a nova sintaxe.
type | null
O símbolo de barra | tem o significado de um OR lógico na sintaxe, criando uma união de dois conjuntos distintos de tipos: o tipo subjacente e a referência anulável. Este é o mesmo símbolo sintático usado para declarar múltiplos casos de uma união discriminada em F#: type AB = A | B carrega o significado de qualquer um A ou B.
A anotação anulável | null pode ser usada em todos os locais em que um tipo de referência normalmente seria usado:
- Campos de tipos de união, tipos de registro e tipos personalizados.
- Aliases de tipo para tipos existentes.
- Digite aplicações de um tipo genérico.
- Anotações de tipo explícitas para permitir associações, parâmetros ou tipos de retorno.
- Digite anotações em constructos de programação de objeto, como membros, propriedades ou campos.
type AB = A | B
type AbNull = AB | null
type RecordField = { X: string | null }
type TupleField = string * string | null
type NestedGenerics = { Z : List<List<string | null> | null> | null }
O símbolo de barra | tem outros usos em F# que podem levar a ambiguidades sintáticas. Nesses casos, parênteses são necessários em torno do tipo anotado como nulo.
// Unexpected symbol '|' (directly before 'null') in member definition
type DUField = N of string | null
Encapsular o mesmo tipo em um par de parênteses ( ) corrige o problema:
type DUField = N of (string | null)
Quando usado na correspondência de padrões, | é usado para separar cláusulas de correspondência de padrões diferentes.
match x with
| ?: string | null -> ...
Esse snippet é, na verdade, equivalente ao código primeiro fazendo um teste de tipo no tipo string e, em seguida, tendo uma cláusula separada para lidar com nulo:
match x with
| ?: string
| null -> ...
Importante
Os recursos adicionais relacionados a nulos foram adicionados ao idioma para fins de interoperabilidade. Usar | null na modelagem de tipos em F# não é considerado idiomático para denotar informações ausentes – para essa finalidade, use opções (conforme descrito acima). Leia mais sobre convenções relacionadas a nulos no guia de estilo.