为什么在“try”中声明的变量范围在“捕获”或“最后” [英] Why aren't variables declared in "try" in scope in "catch" or "finally"?

查看:125
本文介绍了为什么在“try”中声明的变量范围在“捕获”或“最后”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#和Java(以及可能的其他语言)中,在try块中声明的变量不在相应的catch或finally块中。例如,以下代码不能编译:

In C# and in Java (and possibly other languages as well), variables declared in a "try" block are not in scope in the corresponding "catch" or "finally" blocks. For example, the following code does not compile:

try {
  String s = "test";
  // (more code...)
}
catch {
  Console.Out.WriteLine(s);  //Java fans: think "System.out.println" here instead
}

这个代码,在catch块的引用上发生编译时错误,因为s只在try块的范围内。 (在Java中,编译错误是无法解决的;在C#中,它是该名称在当前上下文中不存在。)

In this code, a compile-time error occurs on the reference to s in the catch block, because s is only in scope in the try block. (In Java, the compile error is "s cannot be resolved"; in C#, it's "The name 's' does not exist in the current context".)

这个问题的一般解决方案似乎是在try块之前声明变量,而不是在try块中:

The general solution to this issue seems to be to instead declare variables just before the try block, instead of within the try block:

String s;
try {
  s = "test";
  // (more code...)
}
catch {
  Console.Out.WriteLine(s);  //Java fans: think "System.out.println" here instead
}

,至少对我来说,(1)这个感觉就像一个笨重的解决方案,(2)它导致变量的范围比程序员所期望的更大(整个方法的剩余部分,而不是在尝试的上下文中) -catch-finally)。

However, at least to me, (1) this feels like a clunky solution, and (2) it results in the variables having a larger scope than the programmer intended (the entire remainder of the method, instead of only in the context of the try-catch-finally).

我的问题是,这种语言设计决策背后的原因是什么(在Java中,在C#和/或任何其他适用的语言)?

My question is, what were/are the rationale(s) behind this language design decision (in Java, in C#, and/or in any other applicable languages)?

推荐答案

两件事:


  1. 一般来说,JavaScript只有2个范围:全局和功能。但是,try / catch是一个例外(没有意图)。当引发异常并且异常对象获取分配给它的变量时,该对象变量仅在catch部分可用,并在catch完成后立即被销毁。
  1. Generally, JavaScript has just 2 levels of scope: global and function. But, try/catch is an exception (no punn intended). When an exception is thrown and the exception object gets a variable assigned to it, that object variable is only available within the "catch" section and is destroyed as soon as the catch completes.

(更重要的是)。你不知道try块在哪里抛出异常。它可能已经在您的变量被声明之前。因此,无法确定catch / finally子句可以使用哪些变量。考虑以下情况,根据您的建议,范围界定如下:

(and more importantly). You can't know where in the try block the exception was thrown. It may have been before your variable was declared. Therefore it is impossible to say what variables will be available for the catch/finally clause. Consider the following case, where scoping is as you suggested:


try
{
    throw new ArgumentException("some operation that throws an exception");
    string s = "blah";
}
catch (e as ArgumentException)
{  
    Console.Out.WriteLine(s);
}


这显然是问题 - 当您到达异常处理程序时,s将不会被声明。鉴于捕获是为了处理特殊情况,最终必须执行,安全并在编译时声明此问题远远优于运行时。

This clearly is a problem - when you reach the exception handler, s will not have been declared. Given that catches are meant to handle exceptional circumstances and finallys must execute, being safe and declaring this a problem at compile time is far better than at runtime.

这篇关于为什么在“try”中声明的变量范围在“捕获”或“最后”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆