为什么我们不能在while循环中定义变量?

Let*_*man 21 c# syntax

我们可以做的:

using (Stream s ..)
Run Code Online (Sandbox Code Playgroud)

和:

for (int i ...)
Run Code Online (Sandbox Code Playgroud)

为什么我们不能这样做:

while ((int i = NextNum()) > 0) {..}
Run Code Online (Sandbox Code Playgroud)

我发现它非常有用和明智.

Mat*_*ell 14

我不是语言设计师,但我会给它一个有根据的猜测.

while()每次循环执行时都会执行子句.(最后+1次.)语句int i = NextNum()声明一个局部变量.您不能多次声明局部变量.

更新

从语义上讲,这应该是可行的.事实上,正如评论中所指出的,这在其他语言中是可能的.但是,如果不重写一些主要的语法规则,这在C#中是不可能的.

必须在语句中声明局部变量.我相信这种语言是这样分开的,因为变量声明并没有真正执行.当您看到一行代码创建一个变量并为其赋值时,这实际上只是两个语句的快捷方式.来自ECMA-334规范:

这个例子

void F() {
   int x = 1, y, z = x * 2;
}
Run Code Online (Sandbox Code Playgroud)

完全对应于

void F() {
   int x; x = 1;
   int y;
   int z; z = x * 2;
}
Run Code Online (Sandbox Code Playgroud)

变量声明部分本身不是"执行"的.它只是意味着应该在堆栈上为某种类型的变量分配一些内存.

while语句期望一个布尔表达式,但表达式不能由语句组成 - 没有特殊的大小写一些新的语法.

for循环是专门设计来声明一个局部变量,但你会注意到,声明部分"执行"只有一次.该using声明专门用于声明局部变量(并处理它们).它也只被"执行"一次.

还要考虑局部变量声明不返回值 - 它不能,因为它允许您声明多个变量.这个陈述会返回哪个值?

int x = 1, y, z = x * 2;
Run Code Online (Sandbox Code Playgroud)

上面的语句是一个局部变量声明.它由一个类型和三个局部变量声明符组成.其中每一个都可以选择包含一个"="标记和一个局部变量初始化程序 允许以这种方式声明局部变量意味着你需要一个类型说明符,因此你可以稍微分开现有的语法,但是强制要求一个声明者,以便它可以返回一个值.

启用此行为也可能产生负面影响,请考虑whiledo/ while语句相反,但是并行.作为语言设计者,您是否还要使do语句声明一个局部变量?我不认为这是可能的.您将无法在循环体中使用该变量,因为它尚未初始化(从第一次运行开始).只有while语句才有可能,但是你会破坏whiledo语句之间的并行性.

  • @dave我不明白..每次迭代创建变量..你不需要它的旧值. (3认同)
  • 没有理由为每次迭代都不能创建和销毁变量(就像循环体中声明的变量一样).其他语言允许这一点. (3认同)

Jar*_*Par 9

不知道肯定,但这是我受过教育的猜测.

for case有效,因为它实际上有3个部分.

  1. 迭代变量
  2. 终止条件
  3. 增量

这3次运行的次数不同.#1只运行一次,#2运行迭代次数+1和#3每次运行运行一次.因为#1只运行一次,所以它是一个定义变量的好地方.

现在让我们检查while循环.它只有1个部分,它每次迭代运行+ 1.由于它每次都运行它不是定义变量的好地方,变量必须是条件的一部分.它提出了类似的问题

  • 定义是否每次迭代发生一次或一次?如果是后者,有多少人会误解这个并弄乱条件?如果它是前者那么你有一个完整的声明,其中每个查询只执行一次部分
  • 多变量定义如何表现?

我猜测复杂性/含糊不清是其不被允许的原因之一.那可能从未在优先级列表中占据优势.