![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=1739347815-MDgpymuRwVT6pthLSFWU8jCAQDrKR7b2-0-32d1d6380520c199b0c749c01d5cb232)
运行结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_124.jpg?sign=1739347815-zAFfilFWeQyzcv6p2wzJ0aCuhsIH3DL4-0-4409303c62158cbfe1e2d66e2cc78940)
在示例中,由于存在4个条件判断依据,因此else不可省略且需要继续判断。
3.6.2 for循环
在实际开发中,for循环非常常用且多用于遍历集合,示例如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_125.jpg?sign=1739347815-1CVk8OFj9smZcmUV4Bnjnfyq3k0YCFl4-0-7fe005a6a7f57333b9e8666bc4877807)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_126.jpg?sign=1739347815-2hVE36BNGMdKNqi8pLXbro1Lw0gHTB9R-0-b7720101c024beff1a69ee9cf5ec5b4f)
在上述代码中,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=1739347815-Eqo6vgVZoCfE5b72ApY8gAOd4A1ii1oD-0-4b5d06c0a86e24f06f125ed030b769a0)
运行结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_128.jpg?sign=1739347815-nkL5alIwdBWCYY7xIl1hHuhGzYLx2FX9-0-5ca15f02a6b1f26a6ba220e83f0bf5e0)
3.6.3 while循环和do-while循环
和for循环不同,while循环没有初始化条件,只有判断是否终止的条件。它在循环的起始进行判断,如果不满足条件,则不会执行循环体。代码如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_129.jpg?sign=1739347815-wAkFWtzqGW1hyxIEGW3Y5YeYwC75CTtU-0-8381606b543eeb92aca67364204b66de)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_130.jpg?sign=1739347815-F3IOfwlZmFr2UQuYIM61CIDU7vS4i7mw-0-9d02e99f64fe826d35a504959bd5f447)
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=1739347815-bIXuv0szKSSbpTjkLuDDITUzbehHSZxo-0-8ef8de7f7e7e259d6f27e921c203fdcc)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_132.jpg?sign=1739347815-X2dHERu5f2y2K9dZ54pKs7obeoEVuOlM-0-e0142e59986d94c1852f703287b5a440)
在上面的代码中,首先执行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=1739347815-gwxnGHrHZZc3LSv6i5lDiRC7Djk3wAAm-0-8fbd311be920eb95f37858c5550983ea)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_134.jpg?sign=1739347815-ukBGQ0cfu8zlhTDtOIlKzQEEa8htqifA-0-64fadeb59be537b27530e14dec838136)
结果是正确的。
在上面的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=1739347815-j2khKCRGOX4EarK8UcfMQhi7mCElaMUw-0-d10569a6e156d696b91efcda5a706071)
输出结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_136.jpg?sign=1739347815-zt4oQ08DPvUMnh3i0Jw6JElBNkUbRQg0-0-758d3296fca0a246464eaf42a65e03e7)
输出结果是正确的。
在上面的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=1739347815-t0FATuX8f85dB7wOqoXwzdxZnblYineg-0-3369caa85f9dfb2d74c7ab2ac35d3124)
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_138.jpg?sign=1739347815-cpgILpiFHSWY7z5HpnRbvySdj4yBUORs-0-f5cc9bb4fefe4f27a1bc04fa0ef5b464)
运行结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_139.jpg?sign=1739347815-gr7BKCuWnCkyxKfiUDe29nyJAnGHGkJL-0-f7c3f6977c4a7140afd36e4bf297939a)
在这段代码中,我们定义了一个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=1739347815-v7PoDOxuQaTfbkavxM8uanjKbTyQqM7O-0-93a263205e4e43ef1d23fdab4a80fa9a)
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_141.jpg?sign=1739347815-RlVhVdQm5DCylGKhZRwUStvufI0Kytvv-0-1c1032be825643261a099f5e5ac8c95f)
运行结果:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_142.jpg?sign=1739347815-EpJD247iKhw4JeQSWv1e02zDpVhdka0V-0-980fbe59bed57c5c8dfe591247860961)
这样雁雁和婷婷的两个case均按照同一种情况进行处理,她们都会收到精装书,显然这不是我们想要的结果。实际上,婷婷和童童应该收到精装书,因此,正确的代码写法如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_143.jpg?sign=1739347815-MZwp8v78bvKkiK6uPNGLqIVJYhZOKGLo-0-6b9308c4b95ba9b68f45ce074b9a6135)
和传统的else if语句相比,switch-case语句结构更加简洁、易懂。
3.6.6 断言
为了方便开发者调试自己的程序,Dart编程语言提供了断言(assert)。因此,断言只在开发模式下起作用,在正式的生产环境(即发布环境)中无效。断言可以检查程序中某些可能出现的运行逻辑错误。如下代码:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt003_144.jpg?sign=1739347815-AUJn1Sghbc41jw6E4XzigzZcmkwDAqDl-0-7caa16756e1c55719a3d1819b82788cf)
很明显,intValue不满足和299相等的条件,此时如果在开发环境中运行程序,就会看到控制台报错。而如果一旦切换到生产模式,则不会收到任何错误提示。这对程序员检查代码中某些隐含的逻辑问题十分有效。