gpt4 book ai didi

scala - 尝试阻止范围

转载 作者:行者123 更新时间:2023-12-03 13:10:18 24 4
gpt4 key购买 nike

我对try块中的变量范围不与关联的catch和finally块共享的规则不满意。具体来说,它导致如下代码:

var v: VType = null

try {
v = new VType()
}
catch {
case e => // handle VType constructor failure (can reference v)
}
finally {
// can reference v.
}


相对于:

try {
val v = new VType()
}
catch {
case e => // handle VType constructor failure (can reference v)
}
finally {
// can reference v.
}


谁能解释或证明为什么Java的这一规则仍然存在?

和/或是否有希望改变这种状况?

谢谢!

更新

非常感谢迄今为止的所有答复。

共识似乎意味着“继续前进”,我开始得出结论,从技术上讲,我想要的东西要么不健全,不值得努力,要么难以实现。

我喜欢雷克斯·克尔(Rex Kerr)的答案,但是上面的原始代码将如何包装在方法调用中而又不在方法主体中引入局部变量?

我自己的工作还不太好,使用一个by-name参数将构造延迟到在try块中可以安全地起作用之前,但是仍然不能让我访问catch或finally块中的构造(或非构造)对象。

最佳答案

您可能会以错误的方式思考问题。为什么在try / catch / finally块中需要这么多东西?在您的代码中

try { val v = new VType() }


返回 v之前可能会引发异常,因此您不能安全地引用 v。但是,如果您不能引用 v,那么在最后一面又不会破坏或抛出自己的异常或有其他一些不良定义的行为,您该怎么办?如果您创建 v但无法创建 w,但是处置也需要同时具有 w,该怎么办? (或者不是吗?)最后一团糟。

但是,如果您来自Java,那么有些事情可以帮助您以明智的方式编写try / catch / finally块。

您可以做的一件事是捕获某些类的异常,然后将它们变成选项:

def s2a(s: String) = try { Some(s.toInt) } catch { case nfe: NumberFormatException => None}


您可以做的另一件事是创建自己的资源管理器

def enclosed[C <: { def close() }](c: C)(f: C => Unit) {
try { f(c) } finally { c.close() }
}
enclosed(new FileInputStream(myFile))(fis => {
fis.read...
}


或者,您可以在另一个方法中创建自己的关闭并安全逃生方法:

val r = valuableOpenResource()
def attempt[F](f: => F) = {
try { f } catch { case re: ReasonableException => r.close() throw re }
}
doSomethingSafe()
attempt( doSomethingDangerous() )
doSomethingElseSafe()
r.close()


在这两种不同的处理方式之间,我并没有太多需要创建var来保存要稍后清除或以catch或finally块处理的变量。

关于scala - 尝试阻止范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3587746/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com