问题描述
如果我编写以下F#代码,则编译器将发出错误消息.
If I write the following F# code, the compiler issues an error.
let a = 123
let a = 123
产生的错误是:
如果我在这样的函数中编写相同的代码:
If I write the same code in a function like this:
let fctn =
let a =123
let a =123
a
它不会产生任何错误.
我不明白区别.谁能解释一下?
I don't understand the difference. Can anyone please explain?
我在模块级别编写的第一个代码.
Edit : first code I write in module level.
推荐答案
我同意这令人困惑.问题是let
用作局部变量(在函数内)和用作全局定义(在模块内)时,行为会有所不同.
I agree this is confusing. The problem is that let
behaves differently when it is used as a local variable (within a function) and when it is used as a global definition (within a module).
全局定义(在模块中)被编译为静态类的静态成员,因此名称只能使用一次.这意味着顶级用途:
Global definitions (in a module) are compiled as static members of a static class and so a name can be used only once. This means that top-level use of:
let a = 10
let a = 11
...是一个错误,因为F#必须产生两个同名的静态成员.
... is an error, because F# would have to produce two static members of the same name.
本地定义(在函数或其他嵌套作用域内部)被编译为IL,并且变量名实际上消失了(IL使用堆栈代替).在这种情况下,F#允许变量阴影化,并且您可以隐藏现有名称的变量.这可以在函数内部,甚至可以是do
块:
Local definitions (inside a function or other nested scope) is compiled to IL and the variable name essentially disappears (the IL uses stack instead). In this case, F# allows variable shadowing and you can hide variable of existing name. This can be inside a function, or even just a do
block:
do
let a = 10
let a = 11
()
这有点令人困惑,因为变量阴影仅在局部作用域内起作用,而在顶级作用域内不起作用.当您知道事物是如何编译时,这才有意义.
This is a bit confusing, because variable shadowing only works inside local scopes but not at the top level. It makes sense when you know how things are compiled though..
这篇关于有时会出现FS0037错误,非常令人困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!