为什么使用“use”比使用“using”更好?

19
根据这个MSDN页面上的最后一句话,应该首选use而不是using。我在其他地方也听说过(例如,这个答案)。为什么呢?我知道use是后来才添加的,但是有什么区别吗?表面上看,using似乎更有用,因为你可以控制何时调用Dispose(),并且如果需要,你可以明确地忽略绑定值(例如,(fun _ -> ...))。
(Note: Please keep the HTML tags intact and only return the translated result.)
4个回答

21

您也可以使用use来控制何时调用dispose,只需使用常见的作用域构造(如括号或begin-end)即可,例如:

let F() =
    let x = 4
    (
        use file = System.IO.File.Open("foo.xml", System.IO.FileMode.Append)
        let z = 4
        printfn "file still open here"
    )
    printfn "file was already closed/disposed"

但我认为这很少有用。 我认为不想命名/使用IDisposable对象也很少见。 use在语法上更加方便,95%的情况下可以满足您的需求,因此我认为它更受欢迎。


2
这种语法上的奇怪似乎是支持“using”的另一个原因。你知道它们是否会产生不同的IL吗? - Daniel
我预计它们会产生类似的IL,但我不知道也不关心。至于语法上的怪异,同样地,没有人编写这样的代码,因为没有人在意Dispose是在函数结束前两行调用还是在函数结束时调用。这种情况非常罕见。只需使用use即可。 - Brian
有一种情况需要您在 use 作用域结束后编写某些代码,即如果您需要正确测试已释放的对象(锁定的文件再次可写)或例如使用信号量。不过,只需将 use 包装在一个函数中,在调用该函数后调用释放后的代码即可,不需要像本例中进行作用域控制。 - Abel
有趣的是,似乎每个人都忽略了使用 use ... in ... 语法来控制作用域。我甚至不知道你展示的这种括号方式也可以实现;我以为唯一的方法就是使用 in。例如:https://gist.github.com/jwosty/cfbf9cc67e9d051f2194895d37298cf9 - Jwosty

16
我认为偏爱使用use的原因就在于其语法更简单。许多其他语言结构都可以表示为函数(例如try .. withforwhile等)。如果语言设计者添加了一个更简单的语法,为什么不使用它...
正如我在您引用的早期答案中所写的那样,即使使用use,您也可以精确控制范围。(这样,您甚至可以在对象表达式类声明的构造函数中使用它。)但大多数情况下,自动行为就足够了(这使得该结构比C#中的using更简单)。
在需要明确控制作用域的情况下,您将使用use还是using取决于个人口味。如果您不喜欢use的显式作用域(我承认有点奇怪,但对我来说很好用),则可以使用using编辑:在类声明中,您不能编写以下内容:
type Foo() =
  use a = new Whatever()
  // ...

因为a的作用域可能是整个实例的生命周期。(尽管我认为这可能很有用,并且它可以自动将IDisposable的实现添加到您的类型中)。如果使用using,则不会遇到这种麻烦。


1
我尝试了一下对象表达式,但无法理解您提到的限制。您能否详细说明一下? - Daniel
@Daniel:抱歉,我想说的是类声明,而不是对象表达式! - Tomas Petricek
我仍然没有找到限制。using 在构造函数内似乎运行良好。 - Daniel
对不起,我误解了。我以为限制适用于“using”。感谢您的解释。 - Daniel

3

个人而言,在相同的情况下,我更喜欢使用use而不是using,原因是我更喜欢简洁明了的表达。

let a = some_expr
some_stuff_with_a

为了

(fun a -> some_stuff_with_a) some_expr

使用绑定表单,通常可以避免一组括号,并且标识符与其绑定的值之间的关联更加紧密,更易于观察。

0

一个反对use的例子,比using更好:

usinguse更好,因为using可以写在一行,而use不能。

例如,
xx是一个函数,通过函数fct从由yy使用给定参数p打开的资源返回值。

let xx p = using (yy(p)) (fun resource-> fct resource)     // <-- this is OK

let xx p  = (use resource = yy(p); fct resource)           // <-- this is Not OK

10
дҪ йңҖиҰҒдҪҝз”Ёinе…ій”®еӯ—пјҢдҫӢеҰӮпјҡ let xx p = (use resource = yy(p) in fct resource)гҖӮе…¶дёӯ yy(p) жҳҜиҺ·еҸ–иө„жәҗзҡ„еҮҪж•°пјҢfct resource жҳҜеҜ№иө„жәҗиҝӣиЎҢж“ҚдҪңзҡ„еҮҪж•°гҖӮ - Tarmil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接