首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >命名块限制变量范围:好主意?

命名块限制变量范围:好主意?
EN

Stack Overflow用户
提问于 2008-10-15 16:42:12
回答 13查看 9.1K关注 0票数 46

多年来,我一直使用命名块来限制临时变量的范围。我从来没有见过这样的事情发生在其他地方,这让我怀疑这是否是个坏主意。特别是因为Eclipse默认将这些标记为警告。

我认为,在我自己的代码中,使用这个方法效果很好。但是,由于这是不习惯的,以至于当优秀的程序员看到它的时候,他们会不信任它,所以我有两条路可走:

  1. 避免这样做,或
  2. 推广它,希望它能成为一个成语。

示例(在更大的方法中):

代码语言:javascript
复制
final Date nextTuesday;
initNextTuesday: {
    GregorianCalendar cal = new GregorianCalendar();
    ... // About 5-10 lines of setting the calendar fields
    nextTuesday = cal.getTime();
}

这里我使用一个GregorianCalendar来初始化一个日期,我想确保我不会意外地重用它。

有些人评论说,你其实不需要命名块。虽然这是真的,但是一个原始块看起来更像一个bug,因为它的意图还不清楚。此外,命名某物会鼓励你考虑块的意图。这里的目标是识别不同的代码部分,而不是赋予每个临时变量它自己的作用域。

许多人评论说,最好直接采用小方法。我同意这应该是你的第一反应。然而,可能有几个减轻因素:

  • 甚至考虑一个命名的块,代码应该是短的,一次性的代码,永远不会被其他地方调用。
  • 命名块是一种快速的方法来组织一个超大的方法,而不创建一个一次性的方法与十几个参数。尤其是当类处于变化中时,输入可能会在不同版本之间发生变化。
  • 创建一个新的方法会鼓励它的重用,如果用例没有很好地建立起来,这可能是不明智的。命名块更容易(至少在心理上)丢弃。
  • 特别是对于单元测试,您可能需要为一次性断言定义十几个不同的对象,而且它们的不同程度使您无法(还)找到将它们合并成少量方法的方法,您也无法想出一种方法来区分它们与长度不到一英里的名称。

使用命名范围的优点:

  1. 不能偶然重用临时变量
  2. 有限的范围为垃圾收集器和JIT编译器提供了更多关于程序员意图的信息。
  3. 块名提供了对代码块的注释,我发现它比开放式注释更具可读性。
  4. 将大方法中的代码重构为小方法更容易,反之亦然,因为命名块比非结构化代码更容易分离。

缺点:

不是惯用的:没有见过这种命名块的使用的程序员(也就是说,除了我之外的每个人)都认为它是错误的,因为他们找不到对块名的引用。(就像Eclipse一样。)让某件事成为成语是一场艰难的战斗。

它可以作为不良编程习惯的借口,例如:

  • 做出巨大的,单一的方法,其中几个小的方法将更容易读懂。
  • 多层压痕太深,不易阅读。

注:我根据一些深思熟虑的回答,对这个问题进行了广泛的编辑。谢谢!

EN

回答 13

Stack Overflow用户

发布于 2008-10-15 16:44:28

我只想直接把它重构成更小的方法。如果一个方法足够大以至于需要像这样分解,那么它确实需要分解成多个方法(如果可能的话)。

虽然限制作用域很好,但这并不是命名块的真正目的。它是统一的,这很少是一件好事。

票数 26
EN

Stack Overflow用户

发布于 2008-10-15 16:48:11

如果这是不好的,那么为什么这是语言中的一个特性!这是有目的的,你已经找到了。

我经常编写与您的示例完全相同的代码。当您想初始化一个变量时,需要做一些计算来确定应该是什么,这涉及到两个变量.然后,您不希望这些变量在函数的整个作用域中徘徊,那么一个包含初始化的小范围就很好了。

迷你作用域是一种将代码分解为“段落”的简单方法。如果将代码拆分为方法,则当这些方法没有从其他地方调用并且具有需要执行它们的顺序时,这些方法就会变得更难导航。

这始终是一种平衡,但是如果您认为它将是最容易维护的,而且如果它完全内联,它实际上会为您的代码的未来读者增加价值,那么就去做吧。

没有硬性规定。有时,我对同事们过分地把所有东西都放在自己的方法、类或文件中感到厌烦,这就变成了一场噩梦。有个很好的平衡!

票数 16
EN

Stack Overflow用户

发布于 2008-10-15 17:01:42

有时,我使用未命名的块来隔离为准备一些不变的东西所需要的可变的东西。我没有使用标签,而是将块放在不可变变量声明下。

代码语言:javascript
复制
final String example;
{
   final StringBuilder sb = new StringBuilder();
   for(int i = 0; i < 100; i++)
     sb.append(i);
   example = sb.toString();

}

当我找到这个块的其他用途时,或者只是认为它挡了路,我就把它变成一个方法。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/205458

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档