Guy*_*der 5 f# immutability f#-interactive
在阅读John Palmer的答案时,可变值与不可变值重新定义之间的区别是什么?,约翰指出
这种重新定义只适用于fsi.
在使用F#Interactive(fsi)时,我想我下意识地知道它,但从未注意过它.
现在很明显,为什么差异?
更具体地说,请解释fsi和编译器之间的内部结构是如何不同的,这是通过设计或差异的结果发生的?
如果答案可以详细说明持有绑定的内部结构,那将是值得赞赏的.
语义与FSI将交互式提交编译到FSI会话的方式一致:每个交互式提交都被编译为module对后续交互式提交开放.
以下内容与FSI的实际内容非常接近,并说明了绑定阴影如何在交互式提交中起作用:
FSI提交#1: let x = 1;;
module FSI_1 =
let x = 1
open FSI_1 //FSI_1.x is now bound to 1 and available at the top level
Run Code Online (Sandbox Code Playgroud)
FSI提交#2: let x = 2;;
module FSI_2 =
let x = 2
open FSI_2 //FSI_1.x is now shadowed by FSI_2.x which is bound to 2 and available at the top level
Run Code Online (Sandbox Code Playgroud)
您可以通过FSI_ASSEMBLY在FSI应用程序域中使用程序集上的反射来查看动态FSI程序集的编译方式的实际细节.每个交互式提交都是作为一个带有命名模式的模块(.NET类)发出的FSI_####.FsEye使用这些事实来发现FSI顶级绑定的状态:https://code.google.com/p/fseye/source/browse/tags/2.0.1/FsEye/Fsi/SessionQueries.fs#24
关于@ JohnPalmer的答案的关键点是顶层FSI定义不能被改变,当它们被"重新定义"时它们只是被遮蔽.我们可以这样说明如下:
> let x = 1;; //our original definition of x
val x : int = 1
> let f () = x;; //capture x
val f : unit -> int
> let x = 2;; //shadow our original definition of x
val x : int = 2
> f();; //returns the original x value, which is still 1 rather than 2
val it : int = 1
Run Code Online (Sandbox Code Playgroud)