字面值
本文提供一個表格,示範如何在 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 |
原生整數 | 帶正負號整數的原生指標 | n | 123n |
unativeint | 原生指標作為無符號的自然數 | 聯合國 | 0x00002D3Fun |
int64 | 有符號的64位整數 | L | 86L |
uint64 | 不帶正負號的64位自然數位 | UL | 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 |
煳 | Unicode 字元 | 沒有 |
'a' 或 '\u0061' |
字串 | Unicode 字串 | 沒有 | "text\n" 或 @"c:\filename" 或 """<book title="Paradise Lost">""" 或 "string1" + "string2" 另請參閱 Strings。 |
位元組 | ASCII 字元 | B | 'a'B |
byte[] | ASCII 字串 | B | "text"B |
字串或位元組[] | 逐字字串 | @ 前置詞 |
@"\\server\share" (Unicode)@"\\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
子句的情況下進行模式比對。 - 屬性參數。
- 靜態型別提供者引數。
Unicode 字串可以包含明確編碼,您可以使用 \u
後面接著 16 位十六進位程式代碼 (0000 - FFFF), 或 UTF-32 編碼,您可以使用 \U
後面接著代表任何 Unicode 字碼點的 32 位十六進位程式代碼(0000000000 - 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