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

查看:43
本文介绍了为什么“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 cannot be resolved";在C#中,是The name 's' does not exist in the current context".)

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 只有两个级别的范围:全局和函数.但是,try/catch 是一个例外(没有双关语的意思).当抛出异常并且异常对象获得分配给它的变量时,该对象变量仅在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 不会被声明.鉴于 catch 旨在处理异常情况并且 finally 必须执行,因此在编译时安全并声明这是一个问题要比在运行时好得多.

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天全站免登陆