D中的for语和foreach语句

Arl*_*len 15 d

除了句法上的差异,两者本身是否相同?它们都是用核心语言实现的吗?或者是foreach标准库的一部分?就性能而言,如果我选择一个而不是另一个,它会有所作为吗?

Meh*_*dad 15

你应该foreach尽可能使用.

  1. foreach迭代几乎任何东西(甚至元数据,如编译时数据类型); for不能.

    foreach (Type; TypeTuple!(int, long, short)) { pragma(msg, Type); }
    
    Run Code Online (Sandbox Code Playgroud)

    但你不能用for循环做到这一点.

  2. foreach可用于在编译时执行操作(上面的扩展); 例如,如果您有一段重复10次的代码,您可以说:

    template Iota(size_t a, size_t b) //All integers in the range [a, b)
    {
        static if (a < b) { alias TypeTuple!(a, Iota!(a + 1, b)) Iota; }
        else { alias TypeTuple!() Iota; }
    }
    
    foreach (i; Iota!(0, 10)) { int[i] arr; } //Not possible with 'for'
    
    Run Code Online (Sandbox Code Playgroud)

    这将在编译时发生,并i视为常量.(这通常不适用for.)

  3. foreach可以重载,opApply也可以使用范围构造,但for不能.这在迭代树结构(如文件系统中的所有文件夹)时非常方便,因为它实际上允许您使用完全基于堆栈的内存而不是在堆上分配(因为您可以使用递归).

  4. foreach在大多数情况下是首选,因为它可以防止您明确键入数据,这有助于防止出现一些错误.例如,

    for (int i = 0; i < n; i++) { arr[i]++; }
    
    Run Code Online (Sandbox Code Playgroud)

    如果n大于2 ^ 32 - 1 是危险的,但是

    foreach (i; 0 .. n) { arr[i]++; }
    
    Run Code Online (Sandbox Code Playgroud)

    不是,因为编译器会自动为迭代选择正确的类型.这也提高了可读性.


ste*_*han 10

foreach和之间的主要区别for是a foreach-loop 的更高抽象级别.A foreach-loop通常for由编译器降低到某个 -loop.这有(至少)四个优点:

  1. 可读性:foreach (a; someArray) doSomething(a);本质上比可读性更强for (size_t i = 0; i < someArray.length; i++) doSomething(someArray[i]);.如果类型someArray不是简单的数组,这将变得更加清晰.
  2. 灵活性:如果在某个时间点,您决定someArray必须将某个数组的类型 更改为范围或对象(例如,实现并行循环),则foreach保持不变,而 for-loop必须为改变要么使用empty,frontpopFront (在一个范围内的情况下)或opApply或在一个类或结构的情况下,一些其它机制.
  3. 特殊功能,例如迭代类型元组,解码UTF-8和UTF-16字符串.
  4. 性能:foreach-loop允许编译器根据类型(迭代数组,范围,字符串,对象......)以及可能的其他信息(例如类型的大小)决定如何最佳地实现循环.这允许所有类型和其他编译器优化的有效实现,而无需过多担心实现细节.实际上,foreach相对于手动编码的性能for 是混合的.foreach(dchar c; someString) {...}(即在循环时解码UTF-8字符串)非常快.但是foreach(a; someObject) {...},在 someObjectimplements中opApply,它会慢一点(因为循环体被包装到委托中,而opApply通常在循环中调用此委托,这会产生一些开销).像往常一样,这对99.99%的情况下的代码无关紧要,因为foreach总会产生(至少)体面的实现.

主要缺点(除此之外,偶尔还有速度)是有些事情无法完成foreach,即物品的许多突变被循环(例如,在循环体内调整阵列的大小).