为什么没有在“try"中声明变量?在“catch"的范围内还是“终于"? [英] Why aren't variables declared in "try" in scope in "catch" or "finally"?

查看:34
本文介绍了为什么没有在“try"中声明变量?在“catch"的范围内还是“终于"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 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 的引用发生了编译时错误,因为 s 仅在 try 块中的作用域内.(在 Java 中,编译错误是s 无法解析";在 C# 中,它是当前上下文中不存在名称 s".)

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) 它导致变量的范围比程序员预期的要大(方法的整个其余部分,而不仅仅是在try-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. 通常,Java 只有 2 个级别的作用域:全局和函数.但是,try/catch 是一个例外(没有双关语).当抛出异常并且异常对象获得分配给它的变量时,该对象变量仅在catch"部分可用,并在捕获完成后立即销毁.

  1. Generally, Java has just 2 levels of scope: global and function. But, try/catch is an exception (no pun 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"中声明变量?在“catch"的范围内还是“终于"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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