Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Syntax 如何使用let in F#创建新的作用域?_Syntax_F# - Fatal编程技术网

Syntax 如何使用let in F#创建新的作用域?

Syntax 如何使用let in F#创建新的作用域?,syntax,f#,Syntax,F#,我试图在F#中初始化一个XmlDocument,而不污染全局名称空间——我唯一的功能背景来自LISP,在LISP中可以使用“let”创建一个新的作用域。我想到了这个: let doc = let reader = new XmlTextReader("url") let doc = new XmlDocument() doc.Load(reader) doc 当我的第一个解决方案不起作用时,我感到相当惊讶: let doc = new XmlDocument(

我试图在F#中初始化一个XmlDocument,而不污染全局名称空间——我唯一的功能背景来自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!

做我想做的事情的首选方式是什么

你的第一个例子似乎是Don Syme和其他F#爱好者采用的风格。混合
#灯光
和ML风格
让。。在
中似乎不是个好主意

你可以从中阅读一些样品来感受当代的F#风格


还有Don Syme写的。

似乎当你使用“let..in”时,你可以覆盖默认的“#light”设置,即空格是重要的,所以我想这就是在这种情况下发生的情况,以及为什么在第二种情况下你没有得到任何警告/错误(您添加了'in',因此编译器认为您需要显式指定范围)。这似乎有点奇怪,因此可能是一个bug。我相信F#团队的Brian很快会回答这个疑问:-)

无论如何,我认为编译器将您的第二个示例视为(使用更容易编译的示例):

本例先打印“10”,然后打印“1”。当然,这似乎不是很实用,但是当使用
use
关键字时它很有用,该关键字的行为类似于
let
,但适用于
IDisposable
对象,并确保对象在离开作用域时被释放(这与C#中的
using
一样):

编辑
我完全忘了提到重要的一点——编写代码的第一种方式对我来说似乎更自然(它充分利用了F提供的“简单”语法的优点),所以我更喜欢它:-)

问题的一部分可能是“let…in…”是一个表达式,而不是一个语句,因此在顶层使用此构造实际上没有意义。例如,这意味着什么:

let x = 1 in
  x - 5
在高层?似乎编译器应该在顶层将“let…in…”的任何使用标记为错误

另一个问题是xmldocumentapi根本不是以函数式风格编写的,这使得从F#开始使用有点尴尬。我想说,您的第一次尝试与您将要得到的一样好,但如果API允许以下内容,那就太好了:

let doc =
  let reader = new XmlTextReader("url")
  reader.ReadAsDocument()

或者,如果有一个XmlDocument的构造函数使用了XmlReader,但是由于API是无可非议的必需的,那么您就必须去做。

事实上,使用let。。在with中,不需要使用#light选项,尽管从规范来看,它仍然作为可选语法有效。读者仍然在范围内这一事实对我来说确实很奇怪。可能是虫子吧?在我看来,它看起来像虫子。但他在这个例子中混合了很多东西:#光,这个‘’运算符、缩进和“in”。F#的语法远不是优雅的,也不是直观的——合并ML和.NET留下了太多的包袱……哇,很好的一个。如果布瑞恩不回答这个问题,你应该考虑把它发送到fsbgs@微软.com。我打开了bug 4693。避免光照代码中的“让……进来”。
let a = 1
(let a = a + 10
 printfn "%d" a)
printfn "%d" a
let some = new Some()
(use file = new StreamReader(...)
 let txt = file.ReadToEnd()
 printfn "%s" txt)
doSomething() // continue, 'file' is now closed!
let x = 1 in
  x - 5
let doc =
  let reader = new XmlTextReader("url")
  reader.ReadAsDocument()