Compartir a través de


Literales

En este artículo se proporciona una tabla que muestra cómo especificar el tipo de un literal en F#.

Tipos literales

En la tabla siguiente se muestran los tipos literales de F#. Los caracteres que representan dígitos en notación hexadecimal no distinguen mayúsculas de minúsculas; los caracteres que identifican el tipo distinguen mayúsculas de minúsculas.

Tipo Descripción Sufijo o prefijo Ejemplos
sbyte entero de 8 bits con signo y 86y

0b00000101y
byte número natural de 8 bits sin signo uy 86uy

0b00000101uy
int16 entero de 16 bits con signo s 86s
uint16 número natural de 16 bits sin signo nos 86us
int

int32
entero de 32 bits con signo l o ninguno 86

86l
uint

uint32
número natural de 32 bits sin signo u o ul 86u

86ul
nativeint puntero nativo a un número natural con signo n 123n
unativeint puntero nativo como un número natural sin signo un 0x00002D3Fun
int64 entero de 64 bits con signo L 86L
uint64 número natural de 64 bits sin signo UL 86UL
single, float32 Número de punto flotante de 32 bits F o f 4.14F o 4.14f o infinityf o -infinityf
lf 0x00000000lf
float; double Número de punto flotante de 64 bits ninguno 4.14 o 2.3E+32 o 2.3e+32 o infinity o -infinity
LF 0x0000000000000000LF
bigint entero no limitado a representación de 64 bits Yo 9999999999999999999999999999I
decimal número fraccionario representado como un punto fijo o un número racional M o m 0.7833M o 0.7833m
Char Carácter Unicode ninguno 'a' o '\u0061'
Cuerda Cadena Unicode ninguno "text\n"

o

@"c:\filename"

o

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

o

"string1" + "string2"

Vea también Cadenas.
byte carácter ASCII B 'a'B
byte[] Cadena ASCII B "text"B
Cadena o byte[] cadena textual @ prefijo @"\\server\share" (Unicode)

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

Literales con nombre

Los valores destinados a ser constantes se pueden marcar con el atributo literal .

Este atributo tiene el efecto de hacer que un valor se compile como una constante. En el ejemplo siguiente, tanto x como y siguientes son valores inmutables, pero x se evalúa en tiempo de ejecución, mientras que y es una constante en tiempo de compilación.

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

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

Nota

No se pueden utilizar funciones para calcular los valores de [<Literal>] porque los valores literales deben determinarse en tiempo de compilación y no pueden depender de una evaluación en tiempo de ejecución.

¿Por qué las funciones no pueden calcular literales?

El atributo [<Literal>] requiere que los valores se conozcan en tiempo de compilación. Las funciones, incluso si parecen generar salidas constantes, se evalúan en tiempo de ejecución, lo que hace que no sean adecuadas para [<Literal>]. Esta restricción garantiza que los literales se pueden usar de forma segura en escenarios como coincidencia de patrones, argumentos de atributo e interoperabilidad con funciones externas.

Por ejemplo, se producirá un error al intentar asignar el resultado de una función a un literal:

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

Esta distinción también es importante al llamar a una función externa. Por ejemplo, DllImport es un atributo que necesita conocer el valor de myDLL durante la compilación. Sin la declaración [<Literal>], este código no se compilaría:

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

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

En las expresiones de coincidencia de patrones, los identificadores que comienzan con caracteres en minúsculas siempre se tratan como variables que se van a enlazar, en lugar de como literales, por lo que normalmente debe usar mayúsculas iniciales al definir literales.

[<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

Ejemplo de coincidencia de patrones concisa mediante Literales nombrados

Los literales con nombre pueden hacer que la correspondencia de patrones sea más concisa evitando la necesidad de cláusulas when o lógica adicional. Por ejemplo:

[<Literal>]
let ErrorCode = 404

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

Observaciones

Los literales con nombre son útiles para:

  • Coincidencia de patrones sin una cláusula when.
  • Argumentos de atributo.
  • Argumentos de proveedor de tipos estáticos.

Las cadenas Unicode pueden contener codificaciones explícitas que puede especificar mediante \u seguido de un código hexadecimal de 16 bits (0000 - FFFF) o codificaciones UTF-32 que puede especificar mediante \U seguido de un código hexadecimal de 32 bits que representa cualquier punto de código Unicode (00000000 - 0010FFFF).

No se permite el uso de operadores bit a bit distintos de |||.

Enteros en otras bases

Los enteros de 32 bits con signo también se pueden especificar en formato hexadecimal, octal o binario utilizando un prefijo 0x, 0o o 0b, respectivamente.

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

Caracteres de subrayado en literales numéricos

Puede separar dígitos con el carácter de subrayado (_).

let value = 0xDEAD_BEEF

let valueAsBits = 0b1101_1110_1010_1101_1011_1110_1110_1111

let exampleSSN = 123_45_6789

Valores infinitos de punto flotante especiales

Tanto el float como single tipos numéricos de punto flotante tienen valores especiales asociados que representan infinito positivo y negativo.

Valor de F# Tipo de F# Valor de .NET correspondiente
infinity o +infinity float PositiveInfinity
-infinity float NegativeInfinity
infinityf o +infinityf single PositiveInfinity
-infinityf single NegativeInfinity

Estos valores se pueden usar directamente o se devuelven al dividir por un cero de punto flotante o un número demasiado pequeño para representarse mediante el tipo especificado. Por ejemplo:

> 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