问题
I am a bit confused by the Literal keyword and why it is necessary in F#.
Reading the docs, it sounds to me that [<Literal>]
is used to define a constant, however I am a bit confused how this constant differs from all other constants in F#..
Values that are intended to be constants can be marked with the Literal attribute. This attribute has the effect of causing a value to be compiled as a constant.
When I think of a constant, I think of something which is immutable....
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?
Is it because the 'normal' F# values are evaluated lazily and the [<Literal>]
is not evaluated lazily..? is that what they mean with 'compiled as constant'..? or is there something else to it?
回答1:
In your example, x
is an immutable value that is assigned during runtime (but NOT evaluated lazily), whereas y
is assigned during compiletime. As an example,
let myDLL = "foo.dll"
[<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
will not work, because DllImport is an attribute and needs to know the value of myDLL
during compilation. However, this will work:
[<Literal>]
let myDLL = "foo.dll"
[<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
回答2:
If you come from C# background, you can think of Literal
values as const
fields, and non-literal ones as readonly
fields. The same differences apply.
回答3:
I think a better example is what happens in a match
.
This doesn't do what you expect:
let t = 3
match q with
|t -> printfn "this always happens"
|_ -> printfn "this never happens" //and produces a compiler warning
on the other hand:
[<Literal>]
let t = 3
match q with
|t -> printfn "q is 3"
|_ -> printfn "q isn't 3"
So here as the Literal
is a compile time constant we can use it for pattern matching.
来源:https://stackoverflow.com/questions/25472810/how-does-literal-differ-from-other-constants-in-f