Литералы
В этой статье представлена таблица, в которую показано, как указать тип литерала в 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