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

问题描述 投票:-1回答:8

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

但有一件事总是让我感到困惑:

如果运行这两个打印语句,它们将从上到下以正确的顺序打印(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
    }
}

这就是我的错误。如果我有一个长时间运行的for-loop和一个打印语句后,for循环在它下面的print语句运行之前完成了怎么办?

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")

在打印内部的print语句之前,循环必须运行1000万次。那些1000万次迭代比仅打印下面的"before this prints"打印声明更快?

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

ios swift for-loop control-flow
8个回答
2
投票

从根本上说,所有操作都是按照奥列格的答案所述顺序执行的。

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

这不是很深刻的解释,但我试图简单化。希望能帮助到你。


1
投票

您的代码按顺序执行。

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

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

1
投票

有一个很好的理由,因为do-while被称为循环,因为执行控制在for或while循环的块内保持循环,直到满足其中一个条件...

例如

for num in 1...4 {

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

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

line1

line2

line3

line4


line5

1
投票

我试着给你这个想法,就像我对你的问题的评论一样简单。这应该回答你的问题。你也有其他一些答案,但是,与你的理解水平相比,它们中的一些相当模糊。

为了完整性和澄清for(或任何其他循环)的用法,我在这个答案中扩展了这个想法尽可能简单。

for是一种用于重复执行语句的简写语法。您可以使用以下简写语法编写问题中的代码:

/// 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中。



我希望这个广泛的解释能够给你一个循环背后的整体想法。现在您应该能够理解代码执行的控制流程。


0
投票

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


0
投票

并不是后一种打印功能比for循环慢。如果你同时运行for循环和后一个print()函数,你将能够看到它。在上面的代码中,它只是一个序列问题。让我试着通过下面的一个简单例子把它放在你面前。

假设您在A位置,并希望前往距离10公里的位置B.您已经开始步行到达目的地(位置B)。现在,在旅程中,您可以做出以下决定:

  1. 您可以完成整个行程并步行到达位置B(将花费更多时间)。
  2. 在旅程中的任何时候,您都可以选择乘坐电梯并完成其余的距离(比#1快)。
  3. 在您前往B地点的任何时候,您都可以决定完全取消旅程。

可能还有其他一些场景。但是,在任何情况下,您可以在覆盖位置A和位置B之间的距离之前到达位置B吗?

在这里考虑for循环作为位置A和位置B之间的旅程,打印功能是你将在位置B获得的一罐甜蜜糖果。

我希望这说清楚。谢谢。


0
投票

在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")

0
投票

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

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语句执行早于百万循环结果显示。

© www.soinside.com 2019 - 2024. All rights reserved.