我对Literal关键字有点困惑,为什么在F#中有必要.
阅读文档,听起来我[<Literal>]用它来定义一个常量,但是我有点困惑这个常量如何与F#中的所有其他常量不同.
可以使用Literal属性标记要作为常量的值.此属性具有将值编译为常量的效果.
当我想到一个常数时,我会想到一些不可改变的东西......
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?
Run Code Online (Sandbox Code Playgroud)
是因为"普通"F#值被懒惰地评估而且[<Literal>]不会被懒惰地评估.?他们的意思是'编译为常数'..?或者还有别的东西吗?
Joh*_*lds 39
在您的示例中,x是一个在运行时分配的不可变值(但不是懒惰地评估),而是y在编译期间分配的.举个例子,
let myDLL = "foo.dll"
[<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
Run Code Online (Sandbox Code Playgroud)
不起作用,因为DllImport是一个属性,需要知道myDLL编译期间的值.但是,这将有效:
[<Literal>]
let myDLL = "foo.dll"
[<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
Run Code Online (Sandbox Code Playgroud)
Joh*_*mer 11
我认为更好的例子是a match.
这不符合您的期望:
let t = 3
match q with
|t -> printfn "this always happens"
|_ -> printfn "this never happens" //and produces a compiler warning
Run Code Online (Sandbox Code Playgroud)
另一方面:
[<Literal>]
let t = 3
match q with
|t -> printfn "q is 3"
|_ -> printfn "q isn't 3"
Run Code Online (Sandbox Code Playgroud)
因此,这Literal是一个编译时常量,我们可以将它用于模式匹配.