为什么不java& js允许条件中的变量声明

时间:2017-01-09 01:16:28

标签: java compiler-errors compilation

 int a; // why can't I put this in the condition itself
 if((a = readData()) > 0){ 
     // do something..
 }

我想知道为什么java和javascript不允许我在(condition)中声明我的变量。我理解它与变量声明必须是行上的第一件事 - 除了for循环这一事实有关 - 但是底层原因是什么? In C++ it seems like they can do it。如果我误解了,我不知道C ++如此道歉。

4 个答案:

答案 0 :(得分:3)

原因是范围规则的简单性。如果在条件中允许变量声明,则必须定义此类变量的范围,以及声明具有值的含义。两者都不是直截了当的。要求已经定义的表达式中的变量很简单,并且没有缺点。允许这很复杂,并会混淆源。当然,这是 a posteriori 推理。可能只是语言设计师目前还有其他原因。

为什么要关心?底线:因为JLS这么说。

答案 1 :(得分:0)

根据Java语言规范(https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.9),if语句具有以下形式:

if ( Expression ) Statement [else ...]

变量赋值,即AssignmentExpression,只是抽象Expressionhttps://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26)的众多子类型之一,因此您可以使用其结果(恰好是if声明中指定的值。

答案 2 :(得分:-1)

它的简单: If语句定义为:

<thead>
    <tr>
        <th data-field="customer.name" data-align="center" data-sortable="true">customer</th>
        <th data-field="type" data-align="center" data-sortable="true" data-visible="false">type</th>
        <th data-field="description" data-align="center" data-sortable="true">description</th>
        <th data-field="cutter" data-align="center" data-sortable="true" data-visible="false">cutter</th>
        <th data-field="valid_s" data-align="center" data-sortable="true" data-visible="false">valid</th>
    </tr>
</thead>

我们现在可以替代:

if (Boolean) {...

如果我们现在将if (var1 operator var2){... // with "_ operator _" => Boolean 作为var1,我们会得到:

i=1

if ((i=1) operator var2){... // compile error: i cannot resolved to a local variable

int i = 1

显而易见的问题是:if ((int i = 1) operator var2){... 是一个类型声明而不是变量,我们在上面学习了if子句只接受布尔变量或表达式导致布尔值变量......!

答案 3 :(得分:-1)

我对这里的答案不满意,所以像任何普通人一样,我学会了java字节码。好吧,有点......基本的。因此,如果有人读到这一点,请记住,我的发现有一些推断,并可能是不准确的..但它使得感觉为什么它不会发生java(更少在javascript我的头在问这个时),它是这么简单。

现在字节代码部分:

这是我得到的:

    int a = 9;
    System.out.println(a);  // just here to prevent some optimization
    if((a = 18) > 15){
        System.out.println(a);
    }


Code:
   0: bipush        9
   2: istore_1
                          // -- removed the System.out.print -- 
  10: bipush        18
  12: dup
  13: istore_1
  14: bipush        15
  16: if_icmple     26

以下是发生的事情:

0: push 9 onto the stack
2: store it in the var a
10: push 18 onto stack
12: duplicate 18 on top of the stack
13: store it in var a
14 : push 15
16: the if statement if value1 is less than or equal to value2, branch to instruction at branchoffset.

因为在if语句本身之前评估条件的内容,如果我们在条件中声明int a,取决于我们定义int a范围的位置,将会有范围的问题。

如果它在if块内:

如果我们假设int将作为范围限定在if块中,那么在到达它之前它仍然必须被评估,因此超出范围!

换句话说:

while((int a = 9) > 15)

int a = 9将在达到while条件之前进行评估,因此超出了我们刚刚定义的范围。我们不会进入while块,但是a的值很明确!使感觉为什么不发生,不是吗?

如果我们走另一条路,并说这只是一个捷径:

 int a;
 while((a = 9) > 15)

然后语言不一致会带来许多令人困惑的代码!参见for循环,其中定义的变量的范围不在外面,例如。

它仍然没有任何意义,为什么它不可能在javascript中做。但是我并不在乎找不到。

我希望我说清楚,至少它对我有些感觉并且我学到了一些东西。从旁注来看,我认为我的问题不值得投票如此之多,即使答案现在对我来说显而易见。并非stackoverflow上的每个问题都必须是实用的..