Swift - for 循环如何在它下面的行之前完成?

Swift -How does a for loop finish before the line under it?

我是一名自学成才的开发人员。我从未上过大学,也没有上过任何 类 教我编程理论或任何基本概念的课程。我只知道如何构建 iOS 应用程序(通过书籍、视频、聚会和练习),我不知道其他任何东西,因为 Apple 已经用它 Xcode 解决了大部分问题SDK(大多数编译器也是如此)所以我不需要知道任何这些东西。

有一件事一直困扰着我:

如果这 2 个打印语句 运行,它们将以正确的顺序从上到下打印 (control flow)

print("I will print first")
print("I will print second")

如果 for-loop 运行 它将以准确的顺序打印所有数字,直到满足条件:

for num in 1...10 {

    print(num)
    if num == 9 {
        print("done") // the for-loop has to iterate 9 times for it to print
        break
    }
}

这就是让我烦恼的地方。 如果我有一个很长的 运行ning for-loop 和它后面的打印语句,那怎么办? for 循环在它下面的 print 语句之前完成 运行s?

for num in 1...10000000 {

    if num == 10000000 {
        print("why does this print") // the for-loop has to iterate 10 million times for it to print
    }
}

print("before this prints")

循环必须 运行 1000 万次才能打印其中的打印语句。为什么那 1000 万次迭代比仅打印下面的 "before this prints" 打印语句更快?

如果这是一个假设我应该知道但我读过或看过的任何东西都没有解决这个问题的问题,请原谅我。

你的代码是顺序执行的。

如果您希望计算不延迟主线程,请使用另一个线程。

DispatchQueue.global().async {
    for num in 1...10000000 {

        if num == 10000000 {
            print("why does this print") // the for-loop has to iterate 10 million times for it to print
        }
    }
}

print("before this prints")

输出:

before this prints
why does this print

从根本上说,所有操作都是按 Oleg 的回答中所述顺序执行的。

您必须了解的是,像 for loop 语句或 if statements 或其他特殊的东西是运行时的指令。当代码执行到遇到 for loop 指令时,它会在 for 循环内不断执行。它只知道 for 循环 {} 中的这个东西应该执行 n 次才能继续。因此,当 for 循环结束时,它会转到下一行代码并执行那里的任何指令。

这不是很深入的解释,但我试图简单化。希望对你有帮助。

程序顺序执行的编程语言,从C语言开始学习。只有条件语句可以改变执行流程,否则将逐行执行。

iOS里面有个closure的概念,closureexecution花了时间的一段代码。 Closure 不会单独保留程序和 运行 直到它完成。其他代码行将并行执行。这就是为什么您的语句在 loop 之前打印的原因。如果你想在循环后打印,那么你应该这样做:

    DispatchQueue.main.sync {
       for num in 1...10000000 {

           if num == 10000000 {
            print("why does this print") // the for-loop has to iterate 10 million times for it to print
            }
        }
    }
    print("before this prints")

为什么将 for、while、do-while 称为 loop 是有充分理由的,因为执行控制会在 for 或 while 循环的块内循环,直到满足其中一个条件。 ..

例如

for num in 1...4 {

    print("line"\(num))
}
print("line5")

但是对于编译器所以它是顺序的

line1

line2

line3

line4


line5

并不是说后面的print函数比for循环慢。如果您同时 运行 您的 for 循环和后面的 print() 函数,您将能够看到。在上面的代码中,这只是一个顺序问题。让我尝试通过下面的一个简单示例将其呈现在您面前。

假设你在地点A,想去10公里外的地点B。您已经开始步行到达目的地(位置 B)。现在,在旅途中,您可以做出以下决定:

  1. 您可以完成整个行程并步行到达地点B(需要更多时间)。

  2. 在旅途中的任何时候,您都可以选择乘坐交通工具完成剩余的距离(比#1 更快)。

  3. 在前往地点 B 的旅途中,您可以随时决定完全取消旅程。

可能还有其他一些场景。但是,在任何情况下,你能在你走完A地和B地之间的距离之前到达B地吗?

将此处的 for 循环视为位置 A 和位置 B 之间的旅程,打印函数是您将在位置 B 获得的一罐糖果。

我希望这能说明问题。谢谢。

所有循环(如 for、while、do-while 等)都是同步的,控制流是从上到下的。循环将继续 运行 直到达到其终止条件。 这就是为什么第一个循环执行将完成,然后您的外部打印语句将执行的原因。 现在让控制器明白你想要异步地 运行 一些工作你可以这样做:

DispatchQueue.global().async {
    for num in 1...10000000 {

        if num == 10000000 {
            print("why does this print") // the for-loop has to iterate 10 million times for it to print
        }
    }
}

print("before this prints")

输出:

在此打印之前

为什么会这样打印

通过上面的代码行 DispatchQueue.global().async 你告诉控制器你可以在后台 运行 的代码块,当你完成时告诉我答案,这就是为什么你可以看到下面的 print 语句执行早于百万循环结果显示。

在我对你的问题的评论中,我尽量让你的想法尽可能简单。那应该回答你的问题。你也有一些其他的答案,不过,与你目前的理解水平相比,其中一些答案相当模糊。

为了完整性和阐明 for(或任何其他循环)的用法,我将尽可能简单地扩展此答案中的想法。

for 是用于重复执行语句的 shorthand 语法。您问题中的代码可以不用 shorthand 语法编写为:

/// checkpoint #1: variable initialization
var num = 1

/// checkpoint #2: condition checking
if num <= 10000000 { //condition true
    if num == 10000000 { //at this point, num equals to 1, so condition is false
        print("why does this print") //doesn't execute
    }
    /// checkpoint #3: increment value of the variable
    num = num + 1 //at this point, num equals to 2
}

if num <= 10000000 { //condition true
    if num == 10000000 { //at this point, num equals to 2, so condition is false
        print("why does this print") //doesn't execute
    }
    num = num + 1 //at this point, num equals to 3
}

if num <= 10000000 { //condition true
    if num == 10000000 { //at this point, num equals to 3, so condition is false
        print("why does this print") //doesn't execute
    }
    num = num + 1 //at this point, num equals to 4
}

. . .
// upto the point where the above repeated lines reach 10000000 if counted
. . .

if num <= 10000000 { //condition true
    if num == 10000000 { //at this point, num equals to 10000000, so condition is true
        print("why does this print") //this time it executes
    }
    num = num + 1 //at this point, num equals to 10000000 + 1
}

if num <= 10000000 { //condition false
    //doesn't execute anything inside this conditional block
    if num == 10000000 {
        print("why does this print")
    }
    num = num + 1
}

// this is the termination point if loop was used

//after executing the previous statements, this line will be executed
print("before this prints") 

作为程序员,我们很聪明地识别重复语句。而且我们足够聪明,可以让上面的代码更短更简单。这是我们引入loop的时候。找到重复块并将它们放入循环中。


你注意到上面重复的语句了吗?让我们再放一遍:

if num <= 10000000 {
    if num == 10000000 {
        print("why does this print")
    }
    num = num + 1
}

Swift中查看这段代码:

for num in 1...10000000 {
    if num == 10000000 {
        print("why does this print")
    }
}
print("before this prints")

可以用其他语言写成(比如,C):

for(int num = 1; num <= 10000000; num++) {
    if(num == 10000000) {
        printf("why does this print");
    }
}
printf("before this prints");

C 中的上述循环可以分解成多个部分,您可以将其与我在第一段代码中提到的检查点进行比较:

for(int num = 1/*checkpoint #1*/; num <= 10000000/*checkpoint #2*/; num++/*checkpoint #3*/)

现在,由于检查点由 for 循环的语法本身满足,剩下的部分是:

if num == 10000000 {
    print("why does this print")
}

然后将这部分放在 for 循环的大括号 { ... } 中。



我希望这个详尽的解释能让您对循环背后的整体思路有所了解。现在你应该能够理解代码执行的控制流程