Поделиться через


Литералы

В этой статье представлена таблица, в которую показано, как указать тип литерала в F#.

Литеральные типы

В следующей таблице показаны литеральные типы в F#. Символы, представляющие цифры в шестнадцатеричной нотации, не чувствительны к регистру; символы, определяющие тип, чувствительны к регистру.

Тип Описание Суффикс или префикс Примеры
sbyte подписанное 8-разрядное целое число y 86y

0b00000101y
байт 8-разрядное натуральное число без знака uy 86uy

0b00000101uy
int16 подписанное 16-разрядное целое число s 86s
uint16 натуральное 16-разрядное число без знака нас 86us
int

int32
32-разрядное целое число со знаком l или ничего 86

86l
uint

uint32
беззнаковое 32-битное целое число u или ul 86u

86ul
nativeint собственный указатель на подписанный естественный номер n 123n
unativeint нативный указатель как беззнаковое натуральное число un 0x00002D3Fun
int64 64-разрядное целое число со знаком L 86L
uint64 64-разрядное естественное число без знака УЛ 86UL
single, float32 32-разрядное число с плавающей запятой F или f 4.14F или 4.14f или infinityf или -infinityf
лф 0x00000000lf
плавать; двойной 64-разрядное число с плавающей запятой никакой 4.14 или 2.3E+32 или 2.3e+32 или infinity или -infinity
ЛФ 0x0000000000000000LF
bigint целое число не ограничено 64-разрядным представлением Я 9999999999999999999999999999I
десятичный дробное число, представленное как фиксированная точка или рациональное число M или m 0.7833M или 0.7833m
Обугливать Символ Юникода никакой 'a' или '\u0061'
Струна Строка Юникода никакой "text\n"

или

@"c:\filename"

или

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

или

"string1" + "string2"

См. также строки.
байт Символ ASCII B 'a'B
byte[] Строка ASCII B "text"B
Строка или байт[] дословная строка @ префикс @"\\server\share" (Юникод)

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

Именованные литералы

Значения, которые должны быть константами, можно пометить атрибутом Литерал.

Этот атрибут влияет на то, что значение компилируется как константа. В следующем примере как x, так и y ниже являются неизменяемыми значениями, но x вычисляются во время выполнения, а y является константой во время компиляции.

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

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

Заметка

Функции нельзя использовать для вычисления [<Literal>] значений, так как литералы должны быть определены во время компиляции и не могут зависеть от оценки среды выполнения.

Почему функции не могут вычислять литералы

Атрибут [<Literal>] требует, чтобы значения были известны во время компиляции. Функции, даже если они, кажется, создают постоянные выходные данные, оцениваются во время выполнения, что делает их непригодными для [<Literal>]. Это ограничение гарантирует, что литералы можно безопасно использовать в таких сценариях, как сопоставление шаблонов, аргументы атрибутов и взаимодействие с внешними функциями.

Например, попытка присвоить результат функции литералу завершится ошибкой.

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

Это различие также имеет значение при вызове внешней функции . Например, DllImport — это атрибут, который должен знать значение myDLL во время компиляции. Без объявления [<Literal>] этот код не сможет компилироваться:

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

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

В выражениях сопоставления шаблонов идентификаторы, начинающиеся с строчных символов, всегда обрабатываются как переменные для привязки, а не как литералы, поэтому при определении литералы обычно следует использовать начальные буквы.

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

Пример краткого сопоставления шаблонов с помощью именованных литералы

Именованные литералы могут сделать сопоставление с образцом более кратким, избегая необходимости условий when или дополнительной логической обработки. Например:

[<Literal>]
let ErrorCode = 404

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

Замечания

Именованные литералы полезны для:

  • Сопоставление шаблонов без предложения when.
  • Аргументы атрибутов.
  • Аргументы поставщика статических типов.

Строки Юникода могут содержать явные кодировки, которые можно указать с помощью \u за которым следует 16-разрядный шестнадцатеричный код (0000 – FFFF) или кодировки UTF-32, которые можно указать с помощью \U за которым следует 32-разрядный шестнадцатеричный код, представляющий любую точку кода Юникода (000000000 – 0010FFFF).

Использование битовых операторов, отличных от |||, запрещено.

Целые числа в других базах

Подписанные 32-разрядные целые числа также можно указать в шестнадцатеричном, восьмимерном или двоичном файле с помощью 0x, 0o или 0b префикса соответственно.

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

Символы подчеркивания в числовых литералах

Вы можете разделить цифры символом подчеркивания (_).

let value = 0xDEAD_BEEF

let valueAsBits = 0b1101_1110_1010_1101_1011_1110_1110_1111

let exampleSSN = 123_45_6789

Специальные значения чисел с плавающей запятой для бесконечности

Как float, так и single числовые типы с плавающей запятой имеют связанные специальные значения, представляющие положительное и отрицательное бесконечность.

Значение F# Тип F# Соответствующее значение .NET
infinity или +infinity float PositiveInfinity
-infinity float NegativeInfinity
infinityf или +infinityf single PositiveInfinity
-infinityf single NegativeInfinity

Эти значения можно использовать напрямую или они возвращаются при делении на ноль с плавающей запятой или число слишком малым, чтобы быть представленным заданным типом. Например:

> 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