Partilhar via


Literais

Este artigo apresenta uma tabela que explica como definir o tipo de um literal em F#.

Tipos literais

A tabela a seguir mostra os tipos literais em F#. Os caracteres que representam dígitos em notação hexadecimal não diferenciam maiúsculas de minúsculas; Os caracteres que identificam o tipo diferenciam maiúsculas de minúsculas.

Tipo Descrição Sufixo ou prefixo Exemplos
Sbyte inteiro de 8 bits assinado y 86y

0b00000101y
byte Número natural de 8 bits não assinado uy 86uy

0b00000101uy
int16 inteiro de 16 bits assinado s 86s
UINT16 número natural de 16 bits não assinado nós 86us
Int

Int32
inteiro de 32 bits assinado l ou nenhum 86

86l
uint

uint32
Número natural de 32 bits não assinado u ou ul 86u

86ul
Nativeint ponteiro nativo para um número natural assinado n 123n
unativeint ponteiro nativo como um número natural não assinado ONU 0x00002D3Fun
Int64 inteiro de 64 bits assinado L 86L
uint64 número natural de 64 bits não assinado UL 86UL
único, flutuante32 Número de ponto flutuante de 32 bits F ou f 4.14F ou 4.14f ou infinityf ou -infinityf
LF 0x00000000lf
flutuar; duplo Número de ponto flutuante de 64 bits nenhum 4.14 ou 2.3E+32 ou 2.3e+32 ou infinity ou -infinity
LF 0x0000000000000000LF
bigint inteiro não limitado à representação de 64 bits Eu 9999999999999999999999999999I
decimais número fracionário representado como um ponto fixo ou número racional M ou m 0.7833M ou 0.7833m
Char Caractere Unicode nenhum 'a' ou '\u0061'
String Cadeia de caracteres Unicode nenhum "text\n"

ou

@"c:\filename"

ou

"""<book title="Paradise Lost">"""

ou

"string1" + "string2"

Consulte também Strings.
byte Caractere ASCII B 'a'B
byte[] String ASCII B "text"B
String ou byte[] string verbatim @ prefixo @"\\server\share" (Unicode)

@"\\server\share"B (ASCII)

Literais nomeados

Os valores que se destinam a ser constantes podem ser marcados com o atributo Literal.

Esse atributo tem o efeito de fazer com que um valor seja compilado como uma constante. No exemplo a seguir, x e y abaixo são valores imutáveis, mas x é avaliada em tempo de execução, enquanto y é uma constante de tempo de compilação.

let x = "a" + "b" // evaluated at run-time

[<Literal>]
let y = "a" + "b" // evaluated at compile-time

Observação

As funções não podem ser usadas para calcular valores de [<Literal>] porque os literais devem ser determinados em tempo de compilação e não podem depender da avaliação do tempo de execução.

Por que as funções não podem calcular literais

O atributo [<Literal>] requer que os valores sejam conhecidos em tempo de compilação. As funções, mesmo que pareçam produzir saídas constantes, são avaliadas em tempo de execução, tornando-as inadequadas para [<Literal>]. Essa restrição garante que os literais possam ser usados com segurança em cenários como correspondência de padrões, argumentos de atributos e interoperabilidade com funções externas.

Por exemplo, a tentativa de atribuir o resultado de uma função a um literal falhará:

[<Literal>]
let yFunc() = "a" + "b" // error FS0267: this is not a valid constant expression

Esta distinção também é importante quando se chama uma função externa. Por exemplo, DllImport é um atributo que precisa saber o valor de myDLL durante a compilação. Sem a declaração [<Literal>], este código não conseguiria compilar:

[<Literal>]
let myDLL = "foo.dll"

[<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()

Em expressões de correspondência de padrões, os identificadores que começam com caracteres minúsculos são sempre tratados como variáveis a serem vinculadas, em vez de literais, portanto, você geralmente deve usar maiúsculas iniciais ao definir literais.

[<Literal>]
let SomeJson = """{"numbers":[1,2,3,4,5]}"""

[<Literal>]
let Literal1 = "a" + "b"

[<Literal>]
let FileLocation =   __SOURCE_DIRECTORY__ + "/" + __SOURCE_FILE__

[<Literal>]
let Literal2 = 1 ||| 64

[<Literal>]
let Literal3 = System.IO.FileAccess.Read ||| System.IO.FileAccess.Write

Exemplo de correspondência concisa de padrões usando literais nomeados

Os literais nomeados podem tornar a correspondência de padrões mais concisa, evitando a necessidade de cláusulas when ou lógica adicional. Por exemplo:

[<Literal>]
let ErrorCode = 404

let handleResponse code =
    match code with
    | ErrorCode -> "Not Found"
    | _ -> "Other Response"

Comentários

Os literais com nome são úteis para:

  • Correspondência de padrões sem uma cláusula when.
  • Argumentos de atributo.
  • Argumentos de provedor de tipo estático.

As cadeias de caracteres Unicode podem conter codificações explícitas que você pode especificar usando \u seguido por um código hexadecimal de 16 bits (0000 - FFFF) ou codificações UTF-32 que você pode especificar usando \U seguido por um código hexadecimal de 32 bits que representa qualquer ponto de código Unicode (00000000 - 0010FFFF).

O uso de operadores bit a bit diferentes de ||| não é permitido.

Inteiros em outras bases

Inteiros de 32 bits assinados também podem ser especificados em hexadecimal, octal ou binário usando um prefixo 0x, 0o ou 0b, respectivamente.

let numbers = (0x9F, 0o77, 0b1010)
// Result: numbers : int * int * int = (159, 63, 10)

Sublinhados em literais numéricos

Você pode separar dígitos com o caractere sublinhado (_).

let value = 0xDEAD_BEEF

let valueAsBits = 0b1101_1110_1010_1101_1011_1110_1110_1111

let exampleSSN = 123_45_6789

Valores especiais de infinito de ponto flutuante

Tanto o float como single tipos numéricos de vírgula flutuante têm valores especiais associados que representam infinito positivo e negativo.

Valor F# Tipo F# Valor .NET correspondente
infinity ou +infinity float PositiveInfinity
-infinity float NegativeInfinity
infinityf ou +infinityf single PositiveInfinity
-infinityf single NegativeInfinity

Esses valores podem ser usados diretamente ou são retornados ao dividir por um zero de ponto flutuante ou um número muito pequeno para ser representado pelo tipo dado. Por exemplo:

> 1.0/0.0;;
val it: float = infinity

> 1.0/(-0.0);;
val it: float = -infinity

> 1.0/0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
;;
val it: float = infinity