我正在尝试在F#中初始化XmlDocument,而又不污染全局 namespace -我唯一的功能背景来自LISP,在这里LISP可以使用“let”创建新作用域。我想出了这个:
let doc =
let reader = new XmlTextReader("url")
let doc = new XmlDocument()
doc.Load(reader)
doc
当我的第一个解决方案不起作用时,我感到非常惊讶:
let doc = new XmlDocument() in
let reader = new XmlTextReader("url");
doc.Load(reader)
print_any reader.ToString // Still in scope!
我想要做什么的首选方式是什么?
最佳答案
看来,当您使用“let .. in”时,您可以覆盖默认的“#light”设置,即空格很重要,因此我想在这种情况下会发生这种情况,以及为什么您在其中没有收到任何警告/错误第二种情况(您添加了“in”,因此编译器认为您想显式指定范围)。似乎有点怪异,所以可能是一个错误。我敢肯定F#小组的Brian会尽快回答这个问题的:-)。
无论如何,我认为编译器将您的第二个示例视为(使用易于编译的示例):
open System
let ar = new ResizeArray<_>() in
let rnd = new Random();
ar.Add(rnd.Next())
printfn "%A" (rnd.Next())
如果添加括号并编写如下内容,则可以强制其按需要对其进行处理:
let ar = new ResizeArray<_>() in
(let rnd = new Random()
ar.Add(rnd.Next()))
printfn "%A" (rnd.Next())
通常,可以在F#程序的任何位置使用括号来指定范围。例如,您可以编写:
let a = 1
(let a = a + 10
printfn "%d" a)
printfn "%d" a
本示例先打印“10”,然后打印“1”。当然,这似乎不太实用,但是在使用行为类似于
use
的let
关键字但对IDisposable
对象有效并确保对象离开作用域时将其处置(这就像using
时)很有用。在C#中):let some = new Some()
(use file = new StreamReader(...)
let txt = file.ReadToEnd()
printfn "%s" txt)
doSomething() // continue, 'file' is now closed!
编辑:
我完全忘记了重要的一点-第一种编写代码的方式对我来说似乎更自然(并且完全利用了F#提供的“简单” #light语法的优点),所以我更喜欢它:-)。