F# [<;Literal>;]与F中的其他常量有何不同#

F# [<;Literal>;]与F中的其他常量有何不同#,f#,F#,我对Literal关键字以及为什么它在F#中是必要的感到有点困惑 阅读文档时,我觉得[]是用来定义一个常数的,但是我有点困惑,这个常数与F#中的所有其他常数有何不同 可以用 文字属性。此属性的作用是使值 可以编译为常量 当我想到一个常数时,我想到的是一个不可变的东西 let x = "a" + "b" //this is a immutable value, its value is constant [<Literal>] let y = "a" + "b" //this is a

我对Literal关键字以及为什么它在F#中是必要的感到有点困惑

阅读文档时,我觉得
[]
是用来定义一个常数的,但是我有点困惑,这个常数与F#中的所有其他常数有何不同

可以用 文字属性。此属性的作用是使值 可以编译为常量

当我想到一个常数时,我想到的是一个不可变的东西

let x = "a" + "b" //this is a immutable value, its value is constant
[<Literal>]
let y = "a" + "b" //this is also a immutable value, but why is this a special constant?
let x=“a”+“b”//这是一个不可变的值,它的值是常量
[]
设y=“a”+“b”//这也是一个不可变的值,但为什么这是一个特殊的常量?

是否因为“正常”F值是惰性计算的,而
[]
不是惰性计算的。。?这就是“编译为常量”的意思吗。。?或者还有其他原因吗?

在您的示例中,
x
是一个在运行时分配的不可变值(但不是惰性地计算),而
y
是在编译时分配的。例如,

let myDLL = "foo.dll"

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

如果您来自C#背景,您可以将
Literal
值视为
const
字段,而非Literal值视为
readonly
字段。相同的差异也适用。

我认为更好的例子是
匹配中发生的情况

这并没有达到您期望的效果:

let t = 3
match q with
|t -> printfn "this always happens"
|_ -> printfn "this never happens" //and produces a compiler warning
另一方面:

[<Literal>]
let t = 3
match q with
|t -> printfn "q is 3"
|_ -> printfn "q isn't 3"
[]
设t=3
匹配q
|t->printfn“q为3”
|_->printfn“q不是3”

因此,这里的
文字
是一个编译时常量,我们可以使用它进行模式匹配。

您可能还需要注意.NET interop的重要性。修饰的
[]
字段作为常量编译到IL中,这对代码的使用者有一定的影响。例如,请参见。请注意,根据f#命名约定,文本应该是PascalCase。如果您将它们用于模式匹配,这不仅仅是约定:不幸的是,这个示例区分大小写。要按说明工作,文字标识符
t
必须以大写字母开头。对非文字版本使用大写字母会产生额外的编译器警告,但功能相同。
[<Literal>]
let t = 3
match q with
|t -> printfn "q is 3"
|_ -> printfn "q isn't 3"