Scala编程基础9:Scala循环

有的时候,我们可能需要多次执行同一块代码。一般情况下,语句是按顺序执行的:函数中的第一个语句先执行,接着执行第二个语句,以此类推。编程语言提供了更为复杂的执行路径的多种控制结构。循环语句允许我们多次执行一个语句或者语句块,下面是大多数编程语言中循环语句的执行流程图:

image

1.循环类型

Scala语言提供了以下几种循环类型:

  • while循环:先判断循环条件,若为真,执行一遍循环代码块,然后再判断循环条件….直到循环条件为假,或者代码内部遇到满足条件的Breaks.break语句,跳出循环。
  • do-while循环:先执行一遍循环代码块,然后判断循环条件,若为真,继续执行一遍代码块,然后再判断循环条件….直到循环条件为假,或者代码内部遇到满足条件的Breaks.break语句,跳出循环。
  • for循环:需要指定循环计数器,在指定的范围内执行循环代码块,若计数器结束,或者代码内部遇到满足条件的Breaks.break语句,跳出循环。

1.1 while循环

Scala语言中的while循环的格式如下:

while(condition)
{ statement(s);
}

其中,statement(s)可以是一个单独的语句,也可以是几个语句组成的代码块。condition可以是任意的表达式,当为任意非零值时都为 true,当条件为 true 时执行循环体; 当条件为 false 时,退出循环,继续执行后续代码。

while循环的流程图如下所示:

image

注意:while 循环的特点是先判断循环条件,若条件直接为假,则循环体一次都不会被执行。

下面是一个while循环的例子:编辑Test1.scala文本文件,内容如下:

object Test1 {
    def main(args:Array[String]) {
        var a = 10;
        while(a > 0){
            println(a+" ");
            a = a - 1;
        }
        println();
    }
}

编译并执行Test1.scala文件,结果如下:

E:\Scala>scalac Test1.scala
E:\Scala>scala Test1
10 9 8 7 6 5 4 3 2 1

1.2 do-while循环

不像 while 循环在循环头部测试循环条件, do-while 循环是在循环的尾部检查它的条件。do-while 循环与 while 循环类似,但是 do-while 循环会确保至少执行一次循环。do-while循环的格式如下:

do {
statement(s);
} while( condition );

其中,statement(s)可以是一个单独的语句,也可以是几个语句组成的代码块。condition可以是任意的表达式,当为任意非零值时都为 true,当条件为 true 时执行循环体; 当条件为 false 时,退出循环,继续执行后续代码。

do-while循环的流程图如下所示:

image

注意:do-while的条件表达式出现在循环的尾部,所以循环中的 statement(s) 至少会被执行一次。

下面是一个do-while循环的例子:编辑Test2.scala文本文件,内容如下:

object Test2 {
    def main(args: Array[String]) {
        var a = 10;
        do{
            print( a + " " );
            a = a + 1;
        }while(a < 20);
        println();
    }
}

编译并执行Test2.scala文件,结果如下:

E:\Scala>scalac Test2.scala
E:\Scala>scala Test2
10 11 12 13 14 15 16 17 18 19

1.3 for循环

for 循环允许编写一个执行指定次数的循环控制结构。格式如下:

for( var x <- Range ) { statement(s);
}

其中,Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x 赋值。

举个例子:以下是一个使用了i to j语法(包括j)的for循环的实例:

object Test3 {
    def main(args: Array[String]) {
        var a = 0;
        for( a <- 1 to 10) {
            print(a + " ");
        }
        println();
    }
}

编译并执行Test3.scala文件,结果如下:

E:\Scala>scalac Test3.scala
E:\Scala>scala Test3
1 2 3 4 5 6 7 8 9 10

以下是一个使用了i until j语法(不包括j)的for循环的实例:

object Test4 {
    def main(args: Array[String]) {
        var a = 0;
        for( a <- 1 until 10) {
            print(a + " ");
        }
        println();
    }
}

编译并执行Test4.scala文件,结果如下:

E:\Scala>scalac Test4.scala
E:\Scala>scala Test4
1 2 3 4 5 6 7 8 9

在for循环中还可以使用分号[;]来设置多个区间,它将迭代给定区间内所有的可能值。以下实例演示了两个区间的for循环的实例:

object Test5 {
    def main(args: Array[String]) {
        var a = 0;
        var b = 0;
        for( a <- 1 to 3; b <- 4 to 7) {
            println("a = " + a + ", b = " + b);
        }
    }
}

编译并执行Test5.scala文件,结果如下:

E:\Scala>scalac Test5.scala
E:\Scala>scala Test5
a = 1, b = 4
a = 1, b = 5
a = 1, b = 6
a = 1, b = 7
a = 2, b = 4
a = 2, b = 5
a = 2, b = 6
a = 2, b = 7
a = 3, b = 4
a = 3, b = 5

a = 3, b = 6
a = 3, b = 7

1.4 for循环集合

for循环集合的格式如下:

for( var x <- List ){

statement(s);
}

以上语法中, List 变量是一个集合,for 循环会迭代所有集合的元素。

举个例子:

以下实例将循环遍历数字集合。我们使用 List() 来创建集合。在以后章节我们会详细介绍集合。

object Test6 {
    def main(args: Array[String]) {
        var a = 0;
        var numList = List(1,2,3,4,5,6);
        for( a <- numList ) {
            print(a + " ");
        }
        println();
    }
}

编译并执行Test6.scala文件,结果如下:

E:\Scala>scalac Test6.scala
E:\Scala>scala Test6
1 2 3 4 5 6

1.5 for循环过滤

Scala 可以使用一个或多个 if 语句来过滤一些元素。以下是在 for 循环中使用过滤器的语法:

for( x <- List
if condition1; if condition2...
){
statement(s);
}

举个例子:以下是 for 循环中过滤的实例:

object Test7 {
    def main(args: Array[String]) {
        var a = 0;
        var numList = List(1,2,3,4,5,6,7,8,9,10);
        for( a <- numList
             if a != 3; if a < 8
        ) {
            print(a + " ");
        }
        println();
    }
}

编译并执行Test7.scala文件,结果如下:

E:\Scala>scalac Test7.scala
E:\Scala>scala Test7
1 2 4 5 6 7

1.6 for使用yield

可以将 for 循环的返回值作为一个变量存储。语法格式如下:

var retVal = for { var x <- List
if condition1; if condition2...
} yield x

注意大括号中用于保存变量和条件,retVal 是变量, 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。

举个例子:以下实例演示了 for 循环中使用 yield:

object Test8 {
    def main(args: Array[String]) {
        var a = 0;
        var numList = List(1,2,3,4,5,6,7,8,9,10);
        var retVal = for { a <- numList
                           if a != 3; if a < 8
                         } yield a;
        for ( b <- retVal ){
            print(b + " ");
        }
        println();
    }
}

编译并执行Test8.scala文件,结果如下:

E:\Scala>scalac Test8.scala
E:\Scala>scala Test8
1 2 4 5 6 7

2.循环控制语句

循环控制语句改变你代码的执行顺序,通过它你可以实现代码的跳转。Scala 语言中默认是没有 break 语句,但是你在 Scala 2.8 版本后可以使用另外一种方式来实现 break 语句。当在循环中使用break 语句,在执行到该语句时,就会中断循环并执行循环体之后的代码块。Scala 中 break 的语法有点不大一样,格式如下:

// 导入以下包
import scala.util.control._ // 创建 Breaks 对象 val loop = new Breaks;
// 在 breakable 中循环 loop.breakable{
// 循环
for(...){
....
// 循环中断 loop.break;
}
}

下面是含有break语句的程序的流程图:

image

举个例子:以下是含有break语句的程序实例:

import scala.util.control._
object Test9 {
    def main(args: Array[String]) {
        var a = 0;
        val numList = List(1,2,3,4,5,6,7,8,9,10);
        val loop = new Breaks;
        loop.breakable {
            for( a <- numList ) {
                print(a + " ");
                if( a == 4 ) {
                    loop.break;
                }
            }
            println();
        }
    }
}

编译并执行Test9.scala文件,结果如下:

E:\Scala>scalac Test9.scala
E:\Scala>scala Test9
1 2 3 4

以下实例演示了如何中断嵌套循环:

import scala.util.control._
object Test10 {
    def main(args: Array[String]) {
        var a = 0;
        var b = 0;
        val numList1 = List(1,2,3);
        val numList2 = List(11,12,13);
        val outer = new Breaks;
        val inner = new Breaks;
        outer.breakable {
            for( a <- numList1 ) {
                print("a = " + a);
                inner.breakable {
                    for(b <- numList2) {
                        print("b = " + b);
                        if(b == 12){
                            inner.break;
                        }
                    }
                }
            }
        }
    }
}

编译并执行Test10.scala文件,结果如下:

E:\Scala>scalac Test10.scala
E:\Scala>scala Test10
a = 1
b = 11
b = 12
a = 2
b = 11
b = 12
a = 3
b = 11
b = 12

3.无限循环

如果条件永远为 true,则循环将变成无限循环(死循环)。我们可以使用 while 语句来演示无限循环:

object Test11 {
 def main(args: Array[String]) {
 var a = 1;
 while( true ) { print( a + " ");
 }
 }
}

编译并执行Test11.scala文件,结果如下:

E:\Scala>scalac Test11.scala
E:\Scala>scala Test11
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 终止批处理操作吗(Y/N)? y
E:\Scala>

以上代码执行后循环会永久执行下去,可以使用 Ctrl + C 键来中断无限循环。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容