为什么文字默认不是常量?
Why do literals not const by default?
如果 F# 鼓励编写不可变的急切求值数据,为什么 F# 不强制简单的 let 绑定默认为 const
?
我需要显式写入 [<Literal>]
属性。例如:
module ConstVsStaticReadOnly =
[<Literal>]
let ConstInt32 = 1
[<Literal>]
let ConstString = "A" + "B" + "C"
let staticReadOnlyBoolean = true
当您在 .NET 中使用 const
时,所有对它的引用都会在编译时替换为它的值。
听起来不错,直到您意识到它不仅限于定义常量的程序集。引用它的其他程序集也会在编译时复制常量的值。
你可以在一个简单的例子中看到结果:
使用单个模块创建新的 F# 库项目
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
。如果您不知道这种行为,那将是一个惊喜。
一旦创建了 public 常数,它就应该 永远不会 改变。这就是编译器不会隐式创建常量的原因。
如果 F# 鼓励编写不可变的急切求值数据,为什么 F# 不强制简单的 let 绑定默认为 const
?
我需要显式写入 [<Literal>]
属性。例如:
module ConstVsStaticReadOnly =
[<Literal>]
let ConstInt32 = 1
[<Literal>]
let ConstString = "A" + "B" + "C"
let staticReadOnlyBoolean = true
当您在 .NET 中使用 const
时,所有对它的引用都会在编译时替换为它的值。
听起来不错,直到您意识到它不仅限于定义常量的程序集。引用它的其他程序集也会在编译时复制常量的值。
你可以在一个简单的例子中看到结果:
使用单个模块创建新的 F# 库项目
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
。如果您不知道这种行为,那将是一个惊喜。
一旦创建了 public 常数,它就应该 永远不会 改变。这就是编译器不会隐式创建常量的原因。