6

有时,我会编写一些带有比我喜欢的更多括号的代码。

 if(!(new Day((((new Date()) / millisecondsPerDay) % 75)) instanceof oldDay))) { 
    // Bonus points if that condition made any sense to you
 }

很难跟踪我需要放置多少个括号,尤其是当我没有使用 IDE 时会立即告诉我何时出现问题。事实上,我敢打赌上面的例子没有正确匹配括号。我被括号里的死亡错误比我想承认的还要多。

我想知道是否有办法规避这种情况。我可以使用什么技术来避免用这么多括号包装东西?

是否有任何语言具有防止需要这么多括号的机制?例如,我认为添加自动关闭括号的特殊字符和自动打开它们的特殊字符可能会有所帮助。(在下面的例子中<>

if(!(new Day<new Date()) / millisecondsPerDay) % 75> instanceof oldDay>
4

5 回答 5

9

一种可行的替代方法是在条件循环之前预先计算带括号的值。以您的代码为例:

if(!(new Day((((new Date()) / millisecondsPerDay) % 75)) instanceof oldDay))) { 
    // Bonus points if that condition made any sense to you
 }

让我们开始分解它。

Date d1 = new Date();
var factor1 = (d1 / millisecondsPerDay ) % 75;
Day day1 = new Day (factor1);

if (!day1 instanceof oldDay) {
// do something
}

请记住,代码是为人类阅读而编写的,然后才供机器执行。如果你发现了巨大的条件,那么就开始对它们进行预处理并将其分解。如果要花一秒钟以上的时间来弄清楚您的病情正在检查什么,那么它可能太长了。

于 2011-08-26T20:01:57.643 回答
2

嗯,首先我总是喜欢重构这种代码。如果可以的话,我将表达式的一部分提取到变量(或函数,以最适合的套件为准),然后您可以对代码本身更有意义,并且您不需要弄得这么乱

bool isOldDay(int someFactor)
{
    if(someFactor instanceof oldDay) 
    {
        return true;
    }
    return false;

}

var today = new Date();
var particularFactor = today/millisecondsPerDay;
var someFactor = particularFactor % 75
var day = new Day(someFactor);


if(!isOldDay(day)) //Do something

编辑:顺便说一句,如果你想做一些不带括号的事情,你可以尝试这样的事情:Reverse Polish Notation

你可以把它5 + ((1 + 2) * 4) − 3做成这个东西:5 1 2 + 4 * + 3 -。当然,这种形式可能非常接近编译器中计算的堆栈表示。

于 2011-08-26T20:11:32.867 回答
1

如果我遵循:

var a = new Date() / millisecondsPerDay) % 75
var newDay = new Day(a);

if (! newDay instanceof oldDay) {
   //do something
}

如果您无法阅读内联逻辑......只需将其放在多行!;-)

于 2011-08-26T20:05:10.457 回答
1

这么多括号是一个很好的迹象,表明

  1. 作者不了解该语言的运算符优先级。例如,您将构造函数调用包装new Date()在一组完全冗余的括号中(new Date())。除非您的语言与任何普通语言不同,否则该前缀new运算符将比几乎任何其他运算符绑定得更紧密。

  2. 作者不关心可理解性。

使其更易于理解、可测试和可维护。有人下线(很可能是你,会为此感谢你......或诅咒你不这样做)。

一些提示:

  • 了解您的语言的运算符优先级。不要在没有充分理由的情况下添加括号。确实了解运算符优先级的人必须花一些时间弄清楚为什么要放入这些括号:您是否在这里做一些不明显的事情?

  • 打破表达。使用堆栈空间(它很便宜)。

  • 将每个简单的子表达式计算为一个独立的局部变量,建立在前面的变量之上。

  • 使变量名称反映它们所代表的内容。

然后只测试最后的临时。在您的情况下,这看起来是一个布尔值。

编写这样的代码很容易理解(没有复杂的表达式),也很容易测试(简单的表达式更容易检查正确性)。它使识别/定位问题变得更加容易。

于 2011-08-26T20:18:00.427 回答
0

我会说这个问题的答案是否定的,因为所有这些括号的全部意义在于避免表达中的歧义。如果您删除它们,则表达式可能不会以您认为的方式进行评估。

因此,如果有这样的构造<>来修复/添加您丢失的括号,则可能不会将它们添加到您期望的位置。

简单示例(好像需要):

(90 / 100 - 1)

...将评估为...

((90 / 100) - 1) // = -0.1

...或者...

(90 / (100 - 1)) // = 0.90909090...

...而且你没有真正的方法知道它会是哪一个。

唯一的选择是将某些部分移到表达式之外,将结果存储在变量中,这样您就可以在表达式中进行更少的计算。

于 2011-08-26T20:06:48.030 回答