繁体   English   中英

C#'for'循环中的多次初始化

[英]Multiple initialization in C# 'for' loop

我如何(如果可能的话)在 C# for循环中初始化多个不同类型的变量? 例子:

for (MyClass i = 0, int j = 1; j<3; j++,i++)

做不到。 将声明之一放在循环之前:

MyClass i = 0;
for (int j = 1; j < 3; j++, i++)

或者为了对称,他们两个:

MyClass i = 0;
int j = 1;
for (; j < 3; j++, i++)

也有可能其中一个变量比另一个更重要。 在这种情况下,将一个作为循环变量并单独处理另一个可能会更简洁,如下所示:

MyClass i = 0;
for (int j = 0; j < 3; j++)
{
    ...
    i++;
}

请注意,如果ij的类型相同,那么您可以在 for 循环中声明它们:

for (int i = 0, j = 1; j < 3; j++, i++)

当然可以做到。 只需使用dynamic关键字:

public static void Main(string[] args) {
    for (dynamic x = 0, y = new MyClass { a = 20, b = 30 }; x < 100; x++, y.a++, y.b--) {
        Console.Write("X=" + x + " (" + x.GetType() + "\n" +
                      "Y.a=" + y.a + ",Y.b=" + y.b + " (" + y.GetType() + "\n");
     }
}

class MyClass {
    public int a = 0, b = 0;
}

祝你有美好的一天!

是的,这是可以做到的。 您可以初始化不同类型的变量在for语句,但你不能言内不同类型的变量。 为了在 for 语句中初始化不同类型的变量,您必须在 for 循环之前声明所有类型。 例如:

int xx;
string yy;
for(xx=0, yy=""; xx<10; xx++)
    {
    ....
    }

[编辑] 为完整性添加更多信息。 这超出了 OP 的要求,但可能对其他人有帮助。 在for循环中初始化相同类型的变量很简单,只需用逗号分隔初始化即可。 您还可以在第三部分更改多个变量。 在第二个比较部分中不能有多个逗号分隔的部分,但可以使用 && || 和 ! 基于多个变量制作复杂的布尔部分。

for(int i=0, j=0, k=99; i<10 && k<200; i++, j++, k += 2)

但是,创建一个复杂到难以理解发生了什么的 for 语句并不是一个好的做法。

有害吗?

是的,非常如此。 语言解析器有两个重要的职责。 一个是大家都熟悉的工作,把文本转换成可执行程序。 但是重要的,以及是,它可以检测到一个无效的程序,并产生有意义的诊断给程序员,因此他可以修复他的代码。

在非常基础的层面上,语言解析器区分声明语句表达式 花括号语言确实混淆了这种区别,您可以将任何表达式转换为语句,只需在其后放置一个分号即可。 在某些情况下,接受语句内的声明,for(;;) 语句就是一个很好的例子。 最简单的是,这种语法在 C 或 C++ 语言中是完全可以接受的:

int x = 42;
x;

这不是一件好事,它是无意义的代码。 C# 语言提高了标准,它会拒绝。 但不是:

int x = 42;
x++;

添加到语言解析器的特殊规则以接受这一点。

任何花括号语言都不会接受将声明转换为表达式。 那种方式是疯狂的,地图末端的龙,船从边缘掉下来,没有好消息要报告。 逗号运算符要求左手和右手操作数是表达式。 声明不是表达,不是故事的结尾。

我通常将声明放在循环之前,并使用额外的花括号来限制声明的范围:

{ //limit the scope: i, count, iDivisibleBy2, iDivisibleBy3, iDivisibleBy5
    int i = 0, count = 100;
    bool iDivisibleBy2 = true, iDivisibleBy3 = true, iDivisibleBy5 = true;
    for( ; i < count; ++i, iDivisibleBy2 = (i % 2 == 0), iDivisibleBy3 = ( i % 3 == 0 ), iDivisibleBy5 = ( i % 5 == 0 ) )
    {
        //...
    }
}

从 C#7.0 开始,您可以使用解构语法:

for (var (i, j) = (0, (MyClass) 1); j < 3; i++, j++)
{
    Console.WriteLine(i);
}

我假设你已经为 MyClass 定义了所有的重载

internal class MyClass
{
    private MyClass(int i)
    {
        Value = i;
    }

    private int Value { get; set; }

    public static explicit operator MyClass(int i) => new MyClass(i);
    public static implicit operator int(MyClass d) => d.Value;

    public static MyClass operator ++(MyClass a)
    {
        a.Value++;
        return a;
    }
}

从 C# 7 开始,使用元组:

for (var foo = (i:new MyClass(0), j:1); foo.j < 3; foo.i++, foo.j++)) { … }
for (initializer; condition; iterator)
{
    //body
}

初始化部分设置初始条件。 在进入循环之前,本节中的语句仅运行一次。 该部分只能包含以下两个选项之一。

1)局部循环变量的声明和初始化。 该变量是循环的局部变量,不能从循环外部访问。

2) 以下列表中的零个或多个语句表达式,用逗号分隔:

  • 赋值语句;

  • 方法的调用;

  • 前缀或后缀增量表达式,如++i或i++;

  • 前缀或后缀递减表达式,如--i或i--;

  • 使用 new 创建对象;

  • 等待表达;

正如我们所知,编译器的设计并不是为了接受我们期望的方式。 inside a for loop.所以以上是在 for 循环中编写之前必须遵循的规则。

http://msdn.microsoft.com/en-us/library/ch45axte.aspx

让我们找点乐子。 我会让你来决定你是否真的应该在任何地方使用它......:P

在不使用动态关键字的情况下,可以(间接)在 for 循环初始化程序中(间接)声明和初始化任意数量的不同类型的变量。 只需为您的索引变量使用自定义结构。

for(var i = new I1<MyClass>(0, 1); i < 3; i++, i.a++) {
    MyClass myClass = i.a;
}

重载运算符意味着您可以像 int 一样使用“i”。 对于干净的语法,初始化为 0:

for(I1<float> i = 0; i < array.Length; i++) {
    i.a += array[i]; // accumulate a float value
}

再举几个愚蠢的例子:

// Three variables
for(I3<object, string, int> i = 0; i < 100; i++) {
    i.a = new object();
    i.b = "This is index " + i;
    i.c = 100 - i;
}

// A class
for(var i = new I1<SomeClass>(0, new SomeClass()); i < 20; i += 2) {
    i.a.someVar1 = "We can have even more variables in here! Woot!";
    i.a.DoSomething(i);
}

// An array
for(var i = new I1<string[]>(0, new[] { "Hi", "Mom" }); i < 10; i++) {
    for(int j = 0; j < i.a.Length; j++) {
        Log(i.a[j]);
    }
}

这是结构。 它们确实有效,但没有经过彻底测试,因此可能存在错误:

public struct I1<T> {

    public int index;
    public T a;

    public I1(int index) {
        this.index = index;
        this.a = default(T);
    }
    public I1(int index, T a) {
        this.index = index;
        this.a = a;
    }

    public override bool Equals(object obj) {
        if(!(obj is I1<T>)) return false;
        I1<T> other = (I1<T>)obj;
        return index == other.index && EqualityComparer<T>.Default.Equals(a, other.a);
    }

    public override int GetHashCode() {
        int hash = 17;
        hash = hash * 29 + index.GetHashCode();
        if(typeof(T).IsValueType && !object.ReferenceEquals(a, null)) hash = hash * 29 + a.GetHashCode();
        return hash;
    }

    public override string ToString() {
        return index.ToString();
    }

    public static implicit operator I1<T>(int other) {
        return new I1<T>(other);
    }

    public static implicit operator int(I1<T> other) {
        return other.index;
    }

    // Unary operators

    public static int operator +(I1<T> a) {
        return +a.index;
    }

    public static int operator -(I1<T> a) {
        return -a.index;
    }

    public static int operator ~(I1<T> a) {
        return ~a.index;
    }

    public static I1<T> operator ++(I1<T> a) {
        a.index++;
        return a;
    }

    public static I1<T> operator --(I1<T> a) {
        a.index--;
        return a;
    }

    // Binary operators

    public static I1<T> operator +(I1<T> a, int b) {
        a.index += b;
        return a;
    }
    public static I1<T> operator +(int a, I1<T> b) {
        b.index += a;
        return b;
    }

    public static I1<T> operator -(I1<T> a, int b) {
        a.index -= b;
        return a;
    }
    public static I1<T> operator -(int a, I1<T> b) {
        b.index = a - b.index;
        return b;
    }

    public static I1<T> operator *(I1<T> a, int b) {
        a.index *= b;
        return a;
    }
    public static I1<T> operator *(int a, I1<T> b) {
        b.index *= a;
        return b;
    }

    public static I1<T> operator /(I1<T> a, int b) {
        a.index /= b;
        return a;
    }
    public static I1<T> operator /(int a, I1<T> b) {
        b.index = a / b.index;
        return b;
    }

    public static I1<T> operator %(I1<T> a, int b) {
        a.index %= b;
        return a;
    }
    public static I1<T> operator %(int a, I1<T> b) {
        b.index = a % b.index;
        return b;
    }

    public static I1<T> operator &(I1<T> a, int b) {
        a.index &= b;
        return a;
    }
    public static I1<T> operator &(int a, I1<T> b) {
        b.index = a & b.index;
        return b;
    }

    public static I1<T> operator |(I1<T> a, int b) {
        a.index |= b;
        return a;
    }
    public static I1<T> operator |(int a, I1<T> b) {
        b.index = a | b.index;
        return b;
    }

    public static I1<T> operator ^(I1<T> a, int b) {
        a.index ^= b;
        return a;
    }
    public static I1<T> operator ^(int a, I1<T> b) {
        b.index = a ^ b.index;
        return b;
    }

    public static I1<T> operator <<(I1<T> a, int b) {
        a.index <<= b;
        return a;
    }

    public static I1<T> operator >>(I1<T> a, int b) {
        a.index >>= b;
        return a;
    }

    // Comparison operators

    public static bool operator ==(I1<T> a, int b) {
        return a.index == b;
    }
    public static bool operator ==(int a, I1<T> b) {
        return a == b.index;
    }

    public static bool operator !=(I1<T> a, int b) {
        return a.index != b;
    }
    public static bool operator !=(int a, I1<T> b) {
        return a != b.index;
    }

    public static bool operator <(I1<T> a, int b) {
        return a.index < b;
    }
    public static bool operator <(int a, I1<T> b) {
        return a < b.index;
    }

    public static bool operator >(I1<T> a, int b) {
        return a.index > b;
    }
    public static bool operator >(int a, I1<T> b) {
        return a > b.index;
    }

    public static bool operator <=(I1<T> a, int b) {
        return a.index <= b;
    }
    public static bool operator <=(int a, I1<T> b) {
        return a <= b.index;
    }

    public static bool operator >=(I1<T> a, int b) {
        return a.index >= b;
    }
    public static bool operator >=(int a, I1<T> b) {
        return a >= b.index;
    }
}

public struct I2<T1, T2> {

    public int index;
    public T1 a;
    public T2 b;

    public I2(int index) {
        this.index = index;
        this.a = default(T1);
        this.b = default(T2);
    }
    public I2(int index, T1 a) {
        this.index = index;
        this.a = a;
        this.b = default(T2);
    }
    public I2(int index, T1 a, T2 b) {
        this.index = index;
        this.a = a;
        this.b = b;
    }

    public override bool Equals(object obj) {
        if(!(obj is I2<T1, T2>)) return false;
        I2<T1, T2> other = (I2<T1, T2>)obj;
        return index == other.index && EqualityComparer<T1>.Default.Equals(a, other.a) && EqualityComparer<T2>.Default.Equals(b, other.b);
    }

    public override int GetHashCode() {
        int hash = 17;
        hash = hash * 29 + index.GetHashCode();
        if(typeof(T1).IsValueType && !object.ReferenceEquals(a, null)) hash = hash * 29 + a.GetHashCode();
        if(typeof(T2).IsValueType && !object.ReferenceEquals(b, null)) hash = hash * 29 + b.GetHashCode();
        return hash;
    }

    public override string ToString() {
        return index.ToString();
    }

    public static implicit operator I2<T1, T2>(int other) {
        return new I2<T1, T2>(other);
    }

    public static implicit operator int(I2<T1, T2> other) {
        return other.index;
    }

    // Unary operators

    public static int operator +(I2<T1, T2> a) {
        return +a.index;
    }

    public static int operator -(I2<T1, T2> a) {
        return -a.index;
    }

    public static int operator ~(I2<T1, T2> a) {
        return ~a.index;
    }

    public static I2<T1, T2> operator ++(I2<T1, T2> a) {
        a.index++;
        return a;
    }

    public static I2<T1, T2> operator --(I2<T1, T2> a) {
        a.index--;
        return a;
    }

    // Binary operators

    public static I2<T1, T2> operator +(I2<T1, T2> a, int b) {
        a.index += b;
        return a;
    }
    public static I2<T1, T2> operator +(int a, I2<T1, T2> b) {
        b.index += a;
        return b;
    }

    public static I2<T1, T2> operator -(I2<T1, T2> a, int b) {
        a.index -= b;
        return a;
    }
    public static I2<T1, T2> operator -(int a, I2<T1, T2> b) {
        b.index = a - b.index;
        return b;
    }

    public static I2<T1, T2> operator *(I2<T1, T2> a, int b) {
        a.index *= b;
        return a;
    }
    public static I2<T1, T2> operator *(int a, I2<T1, T2> b) {
        b.index *= a;
        return b;
    }

    public static I2<T1, T2> operator /(I2<T1, T2> a, int b) {
        a.index /= b;
        return a;
    }
    public static I2<T1, T2> operator /(int a, I2<T1, T2> b) {
        b.index = a / b.index;
        return b;
    }

    public static I2<T1, T2> operator %(I2<T1, T2> a, int b) {
        a.index %= b;
        return a;
    }
    public static I2<T1, T2> operator %(int a, I2<T1, T2> b) {
        b.index = a % b.index;
        return b;
    }

    public static I2<T1, T2> operator &(I2<T1, T2> a, int b) {
        a.index &= b;
        return a;
    }
    public static I2<T1, T2> operator &(int a, I2<T1, T2> b) {
        b.index = a & b.index;
        return b;
    }

    public static I2<T1, T2> operator |(I2<T1, T2> a, int b) {
        a.index |= b;
        return a;
    }
    public static I2<T1, T2> operator |(int a, I2<T1, T2> b) {
        b.index = a | b.index;
        return b;
    }

    public static I2<T1, T2> operator ^(I2<T1, T2> a, int b) {
        a.index ^= b;
        return a;
    }
    public static I2<T1, T2> operator ^(int a, I2<T1, T2> b) {
        b.index = a ^ b.index;
        return b;
    }

    public static I2<T1, T2> operator <<(I2<T1, T2> a, int b) {
        a.index <<= b;
        return a;
    }

    public static I2<T1, T2> operator >>(I2<T1, T2> a, int b) {
        a.index >>= b;
        return a;
    }

    // Comparison operators

    public static bool operator ==(I2<T1, T2> a, int b) {
        return a.index == b;
    }
    public static bool operator ==(int a, I2<T1, T2> b) {
        return a == b.index;
    }

    public static bool operator !=(I2<T1, T2> a, int b) {
        return a.index != b;
    }
    public static bool operator !=(int a, I2<T1, T2> b) {
        return a != b.index;
    }

    public static bool operator <(I2<T1, T2> a, int b) {
        return a.index < b;
    }
    public static bool operator <(int a, I2<T1, T2> b) {
        return a < b.index;
    }

    public static bool operator >(I2<T1, T2> a, int b) {
        return a.index > b;
    }
    public static bool operator >(int a, I2<T1, T2> b) {
        return a > b.index;
    }

    public static bool operator <=(I2<T1, T2> a, int b) {
        return a.index <= b;
    }
    public static bool operator <=(int a, I2<T1, T2> b) {
        return a <= b.index;
    }

    public static bool operator >=(I2<T1, T2> a, int b) {
        return a.index >= b;
    }
    public static bool operator >=(int a, I2<T1, T2> b) {
        return a >= b.index;
    }
}

public struct I3<T1, T2, T3> {

    public int index;
    public T1 a;
    public T2 b;
    public T3 c;

    public I3(int index) {
        this.index = index;
        this.a = default(T1);
        this.b = default(T2);
        this.c = default(T3);
    }
    public I3(int index, T1 a) {
        this.index = index;
        this.a = a;
        this.b = default(T2);
        this.c = default(T3);
    }
    public I3(int index, T1 a, T2 b) {
        this.index = index;
        this.a = a;
        this.b = b;
        this.c = default(T3);
    }
    public I3(int index, T1 a, T2 b, T3 c) {
        this.index = index;
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public override bool Equals(object obj) {
        if(!(obj is I3<T1, T2, T3>)) return false;
        I3<T1, T2, T3> other = (I3<T1, T2, T3>)obj;
        return index == other.index && EqualityComparer<T1>.Default.Equals(a, other.a) &&
            EqualityComparer<T2>.Default.Equals(b, other.b) &&
            EqualityComparer<T3>.Default.Equals(c, other.c);
    }

    public override int GetHashCode() {
        int hash = 17;
        hash = hash * 29 + index.GetHashCode();
        if(typeof(T1).IsValueType && !object.ReferenceEquals(a, null)) hash = hash * 29 + a.GetHashCode();
        if(typeof(T2).IsValueType && !object.ReferenceEquals(b, null)) hash = hash * 29 + b.GetHashCode();
        if(typeof(T3).IsValueType && !object.ReferenceEquals(c, null)) hash = hash * 29 + c.GetHashCode();
        return hash;
    }

    public override string ToString() {
        return index.ToString();
    }

    public static implicit operator I3<T1, T2, T3>(int other) {
        return new I3<T1, T2, T3>(other);
    }

    public static implicit operator int(I3<T1, T2, T3> other) {
        return other.index;
    }

    // Unary operators

    public static int operator +(I3<T1, T2, T3> a) {
        return +a.index;
    }

    public static int operator -(I3<T1, T2, T3> a) {
        return -a.index;
    }

    public static int operator ~(I3<T1, T2, T3> a) {
        return ~a.index;
    }

    public static I3<T1, T2, T3> operator ++(I3<T1, T2, T3> a) {
        a.index++;
        return a;
    }

    public static I3<T1, T2, T3> operator --(I3<T1, T2, T3> a) {
        a.index--;
        return a;
    }

    // Binary operators

    public static I3<T1, T2, T3> operator +(I3<T1, T2, T3> a, int b) {
        a.index += b;
        return a;
    }
    public static I3<T1, T2, T3> operator +(int a, I3<T1, T2, T3> b) {
        b.index += a;
        return b;
    }

    public static I3<T1, T2, T3> operator -(I3<T1, T2, T3> a, int b) {
        a.index -= b;
        return a;
    }
    public static I3<T1, T2, T3> operator -(int a, I3<T1, T2, T3> b) {
        b.index = a - b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator *(I3<T1, T2, T3> a, int b) {
        a.index *= b;
        return a;
    }
    public static I3<T1, T2, T3> operator *(int a, I3<T1, T2, T3> b) {
        b.index *= a;
        return b;
    }

    public static I3<T1, T2, T3> operator /(I3<T1, T2, T3> a, int b) {
        a.index /= b;
        return a;
    }
    public static I3<T1, T2, T3> operator /(int a, I3<T1, T2, T3> b) {
        b.index = a / b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator %(I3<T1, T2, T3> a, int b) {
        a.index %= b;
        return a;
    }
    public static I3<T1, T2, T3> operator %(int a, I3<T1, T2, T3> b) {
        b.index = a % b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator &(I3<T1, T2, T3> a, int b) {
        a.index &= b;
        return a;
    }
    public static I3<T1, T2, T3> operator &(int a, I3<T1, T2, T3> b) {
        b.index = a & b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator |(I3<T1, T2, T3> a, int b) {
        a.index |= b;
        return a;
    }
    public static I3<T1, T2, T3> operator |(int a, I3<T1, T2, T3> b) {
        b.index = a | b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator ^(I3<T1, T2, T3> a, int b) {
        a.index ^= b;
        return a;
    }
    public static I3<T1, T2, T3> operator ^(int a, I3<T1, T2, T3> b) {
        b.index = a ^ b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator <<(I3<T1, T2, T3> a, int b) {
        a.index <<= b;
        return a;
    }

    public static I3<T1, T2, T3> operator >>(I3<T1, T2, T3> a, int b) {
        a.index >>= b;
        return a;
    }

    // Comparison operators

    public static bool operator ==(I3<T1, T2, T3> a, int b) {
        return a.index == b;
    }
    public static bool operator ==(int a, I3<T1, T2, T3> b) {
        return a == b.index;
    }

    public static bool operator !=(I3<T1, T2, T3> a, int b) {
        return a.index != b;
    }
    public static bool operator !=(int a, I3<T1, T2, T3> b) {
        return a != b.index;
    }

    public static bool operator <(I3<T1, T2, T3> a, int b) {
        return a.index < b;
    }
    public static bool operator <(int a, I3<T1, T2, T3> b) {
        return a < b.index;
    }

    public static bool operator >(I3<T1, T2, T3> a, int b) {
        return a.index > b;
    }
    public static bool operator >(int a, I3<T1, T2, T3> b) {
        return a > b.index;
    }

    public static bool operator <=(I3<T1, T2, T3> a, int b) {
        return a.index <= b;
    }
    public static bool operator <=(int a, I3<T1, T2, T3> b) {
        return a <= b.index;
    }

    public static bool operator >=(I3<T1, T2, T3> a, int b) {
        return a.index >= b;
    }
    public static bool operator >=(int a, I3<T1, T2, T3> b) {
        return a >= b.index;
    }
}

我认为您不能在 for 循环中定义多个类型。 仅 for(int i=0,j=3; j<7; j++, i++)

您不能在循环结构中定义多个变量。 试试下面的代码:

选项 1:在循环之前声明一个变量,每次迭代在循环中手动递增一次。

MyClass i = 0;
for (int j = 1; j<3; j++)
{
  //do stuff
  i++
}

选项2:两个变量在for循环之前设置,一个在循环结构中递增,另一个在循环中手动。

MyClass i = 0;
int j = 1
for (; j<3; j++)
{
  //do stuff
  i++
}

选项3:两个变量都在for循环结构之前设置,两个变量在循环中递增,让循环只检查一个条件,此时你可以只做一个while循环。

MyClass i = 0;
int j = 1
for (; j<3)
{
  //do stuff
  j++
  i++
}

选项 4:写为 while 循环

MyClass i = 0;
int j = 1
while (j<3)
{
  //do stuff
  j++
  i++
}

这不是我的专长,但这是我对这个话题的头脑风暴:

在程序设计语言理论中,语言的语法必须明确定义。 我无法详细介绍它,因为我研究这些主题已经有几年了。 但是您可以查看Backus-Naur Form ,它是一种描述语言“语法”的符号技术。 这是我唯一熟悉的。

所以在解析代码时会用到这个描述。 并且您的解析器必须能够将代码的每一部分与语法的“规则”相关联。 您可以在此处查看 C# 语法。 它有点类似的形式。

(1)看一下for语句的语法

for-statement:
    for(for-initializer;for-condition;for-iterator)   
        embedded-statement

然后是 for-initializer 语法

for-initializer:
    local-variable-declaration
    statement-expression-list

请注意,语句表达式列表仅用于 for 循环。 它也是一个逗号分隔的语句表达式列表。

我会在这里留下一些中间步骤,但你可以按照语法来让自己更适应这个想法。

是一组很好的基本幻灯片,演示了即使使用非常简单的语法,事情也会变得多么复杂。

(2) 我们在 1 中观察到的是我们可以为 for 循环的初始化部分添加什么。 我们知道为什么您的建议不起作用。 作为赏金猎人,让我们分析一下这种设计选择的原因。

首先,它是一种设计选择 您可以设计或找到一种允许这样做的语言。 应该可以通过更改语法来实现,但是可能需要进行一些语法更改。 这是为什么;

如果要放置多个声明语句,则可能需要声明列表之类的内容。 您将要用于分隔符的内容,您可能不想使用 ; 因为分号用于分隔 for 循环的各个部分。 因此,您始终可以使用逗号,但如果您使用逗号,则声明列表规则只能用于 for 循环,因为在您的代码中使用逗号分隔的声明会令人困惑。

其次,这有什么问题? 如果你问我,我也看不出有什么不妥。 如果他们设计了它应该工作的语言。 (我并不是说我刚刚制作的草图是 100% 正确的,它只能用作头脑风暴会议的起点。)

那么,他们为什么选择不这样做呢? 是什么促使他们避免这种情况?

  • 通过将该规则添加到您的语法中,您引入了多少复杂性?
  • 您是否还考虑过必须添加多少附加规则才能使语言明确无误?
  • 您是否意识到现有规则会变得多么复杂?
  • 给您的解析器和编译器增加了多少工作量?

在所有这些和许多其他考虑之后,

  • 你对你的语言的可用性和可读性增加了多少?
  • 或者你甚至会失去一些可读性?
  • 您是否考虑过程序员需要这些类型的 for 循环的频率?
  • 即使他们确实经常需要它,您应该鼓励还是劝阻他们进行这种类型的编码?

……还有很多像这样的问题,必须仔细考虑。 通过查看这些问题及其分析,我会说编译器设计者的设计选择几乎是最可接受的方法。

没有什么理由不在带内初始化备用索引器。 它使环境远离无用的 var 分配。

for (int x=0,y = 0; x < 100; x++)
{
    if (true) {  y++; }
    // ... use y as a conditional indexer
    // ... x is always the loop indexer
    // ... no overflows
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM