与传统的c样式for循环相比,基于范围的for循环有什么好处?

问题描述

我正在实现自己的编程语言,并且对循环语法的选择感到困惑。

似乎所有最新最酷的语言都在使用基于范围的for循环。我努力地搜索了Google的优缺点,唯一的答案似乎是cleaner and cooler。 虽然我可以顺应潮流而变得冷静。我不能说服自己比循环的c风格更好。

我认为支持for(:),foreach,for ... in ...之类的快捷方式很棒,但是不应该将旧的c循环风格用作通用回退吗?

for(int i =0;i<len;++i) {}

因为它非常灵活,可以轻松处理所有可能的情况。对我来说,这是“少即是多”的例子。

有了它,我不需要搜索类似的答案:

using range based for loop for iterating on a sub range

Reverse Range in Swift

https://www.dotnetperls.com/range-swift

Skip 1st Iteration of Range-Based For Loops

我只需要记住一种语法即可完成所有工作。例如,以下代码段实现了行程编码算法。您可以在一个while循环中更新for循环的索引。您不需要不断地前进。您不必预先定义循环行为。

// CPP program to implement run length encoding
#include <bits/stdc++.h>
using namespace std;
 
void printRLE(string str)
{
    int n = str.length();
    for (int i = 0; i < n; i++) {
 
         // Count occurrences of current character
        int count = 1;
        while (i < n - 1 && str[i] == str[i + 1]) {
            count++;
            i++;
        }

        // Print character and its count
        cout << str[i] << count;
    }
}
 
int main()
{
    string str = "wwwwaaadexxxxxxywww";
    printRLE(str);
    return 0;
}

基于范围的循环是否主要用于语言人体工程学?

但是这些不是很丑吗?您最终要输入更多内容才能达到相同的目的。

for i in stride(from:5,through:1,by:-1) { print(i) } // 5 4 3 2 1

for (n,prime) in primes.enumerated() {}

编辑: 在写了最初的问题之后,我微弱地想起了swift似乎一开始就支持c风格的循环,后来又删除了它。查阅历史记录后,我发现了https://github.com/apple/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md,其背后有一些原因。我不认为“不是很像Swift”。虽然很合逻辑...

解决方法

对于任何用例来说,C 风格的循环似乎都足够强大。那么为什么不使用它们呢?

想到的一个原因是安全:从集合中分离索引会导致一系列错误。例如,经典的数组索引越界错误:也许程序员忘记了您的语言是 0 索引的,或者他们将计数器递增了太多次,或者其他地方出了问题——我相信大多数程序员有过这样的经历。相比之下,当您拥有某种基于范围的语法时,就不可能(以这种方式)搞砸。

(当然,你总是可以决定避免这些错误是程序员的工作。毕竟,能力越大,责任越大!许多语言已经决定走这条路,或者至少允许走这条路。我知道至少 one very successful example。)

关于“丑陋”:我实际上发现 C 风格的循环比许多替代品更丑陋。一方面,它通常最终成为额外的样板——for i in range(1...5) { … i … }for (i = 0; i < range(1...5).length(); ++i) { … range(1...5)[i] … } 直接得多。正如我所提到的,精心设计的计数器操作方案很容易搞砸。作为一个更倾向于功能性倾向的人,我会更喜欢一个更能证明正确的方案。

谈到函数式倾向:C 风格的循环可能不适合您的语言范式。在许多语言中,“for 循环”甚至不是一个自然的概念!如果您的主要结构是 s 表达式(如在 Lisp 中),则范围样式循环(又名 map)比 for 循环自然得多。 (如果你想真正纯粹,改变计数器变量也不自然。)我注意到这往往出现在高度关注结构递归的编程语言中(想想 LISP、Haskell、派特等)。结构递归非常棒,因为它的定义非常明确,尤其是与不规则递增的循环相比时。

此时的问题是“但为什么要为函数范式烦恼呢?”可能会出现……但这已在别处广泛讨论。

,

我认为支持像 for(:)、foreach、for ... in... 这样的快捷方式很棒,但不应该支持旧的 c 样式 for 循环作为通用后备吗?

几乎所有命令式语言都支持 while 循环作为通用后备。 for 循环只是一个语法糖,即使是 C 风格的 for 循环。因此,for 本身不如 while 强大,例如因为它限制了可以在任何地方声明的索引变量的范围,如果我们使用 while。当然,您可能会争辩说 while 只是 goto 的语法糖,它更强大... but considered harmful

这一切都取决于你想要什么样的语言。 C 风格的 for 通常用于与基于范围的 for 循环(或 foreach)相同的事情,因此这是一种更清晰、更易读的编写方式。基于范围的 for 让程序员可以专注于迭代的意义而不是实现细节。因此,它比 C 风格的 for 更适合高级语言。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...