为什么文字默认不是常量?

时间:2017-04-24 17:09:00

标签: .net f# functional-programming constants lazy-evaluation

如果F#鼓励编写不可变的热切评估数据,为什么F#默认不强制简单的let绑定为const

我需要明确写出[<Literal>]属性。例如:

module ConstVsStaticReadOnly =

    [<Literal>]
    let ConstInt32 = 1

    [<Literal>]
    let ConstString = "A" + "B" + "C"

    let staticReadOnlyBoolean = true

1 个答案:

答案 0 :(得分:9)

在.NET中使用const时,对它的所有引用都会在编译时被其值替换。

听起来没问题,直到你意识到它不仅限于定义常数的程序集。引用它的其他程序集也将在编译时复制常量的值。

您可以通过一个简单示例查看结果:

使用单个模块创建新的F#Library项目

module ConstTest 

let [<Literal>] ConstInt = 1
let NotConstInt = ConstInt

然后是一个控制台应用程序,其中包含对库的引用

[<EntryPoint>]
let main argv = 
    printfn "%A %A" ConstTest.ConstInt ConstTest.NotConstInt
    0

运行时,会按预期打印1 1

现在修改库中的常量

module ConstTest 

let [<Literal>] ConstInt = 2
let NotConstInt = ConstInt

构建库(但不是控制台应用程序!),将dll复制到控制台应用程序文件夹并运行应用程序。它打印1 2。如果您不了解这种行为,那就太惊讶了。

创建公共常量后,永远不会更改。这就是编译器不会隐式创建常量的原因。