![Flutter从0基础到App上线](https://wfqqreader-1252317822.image.myqcloud.com/cover/259/33831259/b_33831259.jpg)
3.6 流程控制
和其他高级编程语言类似,Dart同样支持流程控制,而且使用方法也十分相似。如果你有其他编程语言的经验,可以跳过本节,但笔者的建议是最好通读一遍,因为有一些写法还是和其他编程语言不同。比如,Java中的for-each这里变成了for-in。
3.6.1 if-else条件语句
Dart编程语言提供if-else结构的流程控制语句,其中if语句是必选的,else可选。示例如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_123.jpg?sign=1738838421-1dB1s9crdEN7tQljVOj03svtrLXX4Sxv-0-6c687cfc10166bca32cd43798116353d)
运行结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_124.jpg?sign=1738838421-td24oKYW33a2EEv8H4Jwkz0dsqW0KADp-0-5d39c3f41e43248043a87fa81f116868)
在示例中,由于存在4个条件判断依据,因此else不可省略且需要继续判断。
3.6.2 for循环
在实际开发中,for循环非常常用且多用于遍历集合,示例如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_125.jpg?sign=1738838421-Ah6lUCZr3mXjZFUNBSzY3poWtlbcL8pt-0-2129a5fc6e800fb4b7e6b24dd88355be)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_126.jpg?sign=1738838421-AMhAoEieJL0TsaTg1hj6IhyhtzJgaEzh-0-90be89d607e1794763a84347469610dc)
在上述代码中,for后面小括号内的内容分别对应循环的初始化(var i=0)、循环的终止条件(i < studentName.length)和每次循环的操作(i++)。在初始化语句中,i=0的意思是从下标索引为0开始取studentName集合的值,使用list.length作为循环结束的判断。在每一次循环过程结束时,i的值自增1,即在下次循环时,取下一个studentName集合中的值。
遍历一个集合是for循环的典型应用且使用相当广泛,是开发者必须要掌握的技巧。
除了上述for循环写法,Dart还提供了一种for循环的简便写法。在讲集合的章节中,提到其无法通过下标来获取值,而这种简便写法可以巧妙地解决这个问题,代码片段如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_127.jpg?sign=1738838421-O0UREaaZ3UFrta3QtM5V7zzBTSbcjPtY-0-3c4bfc1aa9375020c0be70672cf00d0e)
运行结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_128.jpg?sign=1738838421-NDPubaaQ7GH2bTszvmV6yjmSOjKKGEqW-0-7c3a55c0d9ef41f33f2a791cb6dec15f)
3.6.3 while循环和do-while循环
和for循环不同,while循环没有初始化条件,只有判断是否终止的条件。它在循环的起始进行判断,如果不满足条件,则不会执行循环体。代码如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_129.jpg?sign=1738838421-f8UNSt3AjgJA5Vf6rfwGyfQQQunpMEwg-0-4d48e3635f343561e93a1de079cac467)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_130.jpg?sign=1738838421-UBibf0O8JpSosNeScaNVn3ZIHRSBK17p-0-b85b99ec0d20fbf9c958b2fd710b06f3)
while循环以i < 100作为停止循环的判断依据,当满足这个条件时,就执行i++,即自增1。当i增加到100,不再满足while的判断条件时,程序就结束循环,最后输出i的值为100。
和while循环不同,do-while循环是在每次执行完循环后判断是否满足条件,而不是在循环的起始位置进行判断。代码如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_131.jpg?sign=1738838421-6h9AW3LXD2j9b60dr3oyE6uDf8Z776Bo-0-64965f5dc0b93038ab12c5ffa5d70f24)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_132.jpg?sign=1738838421-jzLm85DQEU6lT7FVglWsUeNStETRJkNc-0-f0c95821f2a5a2bd7cdd4c778c3fb130)
在上面的代码中,首先执行j--的循环操作,然后判断是否为j > 0。一开始j的值肯定是大于0的,即满足条件,继续执行循环体。当j的值减小到不再满足j > 0的条件时,程序就结束循环,输出j的结果即0。
3.6.4 break语句和continue语句
break语句和continue语句可以用来控制循环的进行,在某些情况下很实用。考虑一种实际情况:输出从27到100之间第一个可以被26整除的数。我们可以简单地使用循环语句从27开始遍历到100,如果余数为0即得到第一个解。此时,就需要结束循环,而这一操作需要借助break语句来实现。代码如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_133.jpg?sign=1738838421-jytpBSUSumefpoWCLlsBaE4GH23k5QVG-0-7b0a5dc241ed5355326f90cb310ff883)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_134.jpg?sign=1738838421-jS5gColzjDORqOUEHDq7A0EF2GGWM7IN-0-b27787586ad5f6e9b697793d31498725)
结果是正确的。
在上面的for循环体中,通过判断i除以26的余数是否为0,为0即可以被26整除。若不满足条件,for循环就继续执行i++;若满足条件,break语句就起作用,直接阻止for循环继续进行,循环结束。因此,不会看到78的结果。
接下来考虑另外一种实际情况:找出从0到100的整数中,所有可以被10整除的数。代码如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_135.jpg?sign=1738838421-PLNxzIAUBuFQhWSV1z06QRVy0v3kS6xK-0-487e3b612325ee3801d8c23a6b0a477a)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_136.jpg?sign=1738838421-gbDvUWTy2VvqHsExSF6WDdEgu3fQZzh7-0-4575e29df5367cfe1672d854f086c21e)
输出结果是正确的。
在上面的for循环体中,就是判断i除以10余数是否为0。如果为0,输出这个数;反之,停止当前循环,直接开始下一次循环。因此,我们发现,continue语句的作用是结束当前循环并直接开始下一次循环。
3.6.5 switch-case条件语句
对于一个变量与多个条件匹配的情况,使用swtich-case语句将会使代码更具有可读性。当然写成多个else if语句也可以正常运行,但显得冗余。如果把前面送礼物的例子写成一个典型的switch-case语句,代码如下所示:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_137.jpg?sign=1738838421-fGM6dUuck59Mfvik6J5Psb8NRfozo3GT-0-ece6628c3eebbe4d12154403b147adf6)
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_138.jpg?sign=1738838421-ivwl35jZ7uF3yIJbe9kP0REq6D5FVfAk-0-51e8c7223378fd013116a3ab42e79720)
运行结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_139.jpg?sign=1738838421-1aKTTx0aglVI6wJaXsWNuh0QR9sUPaWX-0-431560c9cdade79b0f31559bd67dfba9)
在这段代码中,我们定义了一个name的变量,值为雁雁。在switch后面的小括号内是表示对name变量值的判断。大括号包裹的内容是对name不同的值进行不同的处理。当值为雁雁时,输出唇膏。因此,在最后的结果中,看到了唇膏的输出。
在使用switch-case语句时,有几点需要注意。
在大括号包括的各种case中,default表示默认情况的处理。在上述示例中,如果name的值为彤彤,程序就找不到匹配的case,因此就会执行default中的语句,输出“不知道你是谁,不送了”。
另外,在不同的case中,如果一个case的内容非空,就要用break隔开;否则,就会被接下来case中的语句一起执行。比如,我们去掉case“雁雁”中的print()语句和break语句,代码如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_140.jpg?sign=1738838421-53fseZvOoLRiNgxXSFlFwPon9NLKk2bd-0-5c6490179d93ac006e6216b09cb71af0)
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_141.jpg?sign=1738838421-mbGzW2zWGoVGa7gXhaWxOgoh2pRXrAiW-0-a22aa0aa6550a21544c365a345026c04)
运行结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_142.jpg?sign=1738838421-NjkpDM7oO3VlLAZKUD3yTKqBKDqQtGuF-0-19a2854117d2711843ae85c0a9fd81f8)
这样雁雁和婷婷的两个case均按照同一种情况进行处理,她们都会收到精装书,显然这不是我们想要的结果。实际上,婷婷和童童应该收到精装书,因此,正确的代码写法如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_143.jpg?sign=1738838421-Vi8e0z3EdFH7cc8x4PbIEnIKKqIohHLA-0-8104fca3111cc4dd8081db8613e99907)
和传统的else if语句相比,switch-case语句结构更加简洁、易懂。
3.6.6 断言
为了方便开发者调试自己的程序,Dart编程语言提供了断言(assert)。因此,断言只在开发模式下起作用,在正式的生产环境(即发布环境)中无效。断言可以检查程序中某些可能出现的运行逻辑错误。如下代码:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_144.jpg?sign=1738838421-1WWHfW0DiaX9b05ZcnQyfQDUxxhF1Edp-0-10fa8e583cde622e868c79ff8f663ecc)
很明显,intValue不满足和299相等的条件,此时如果在开发环境中运行程序,就会看到控制台报错。而如果一旦切换到生产模式,则不会收到任何错误提示。这对程序员检查代码中某些隐含的逻辑问题十分有效。