四天掌握Scala(2)

简介: 你好看官,里面请!今天笔者讲的是scala。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。

四天掌握Scala(2)

1.5 循环

在 Scala 中,可以使用 for 和 while,但一般推荐使用 for 表达式,因为 for 表达式语法更简洁。

1.5.1 for 表达式

语法格式如下:

for(i <- 表达式/数组/集合) {
    // 表达式
}

示例: 简单循环,使用 for 表达式打印 1-10 的数字。

步骤:

  1. 生成 1-10 的数字(提示:使用 to 方法)。
  2. 使用 for 表达式遍历,打印每个数字。

参考代码1:

scala> val nums = 1.to(10)
nums: scala.collection.immutable.Range.Inclusive = Range 1 to 10
scala> for(i <- nums) println(i)

参考代码2:

scala> for(i <- 1 to 10) println(i)
1
2
3
4
5
6
7
8
9
10
scala> for(i <- 1 until 10) println(i)
1
2
3
4
5
6
7
8
9

嵌套循环: 使用 for 表达式,打印以下字符。

*****

*****

*****

参考代码

scala> :paste
// Entering paste mode (ctrl-D to finish)
for(i <- 1 to 3){
 for(i <- 1 to 5){
   print("*")
 }
 println()
}
// Exiting paste mode, now interpreting.
*****
*****
*****
scala> for(i <- 1 to 3;j <- 1 to 5){print("*");if(j==5) println("*")}
******
******
******
scala>

也可以在一个 for 中通过 ; 来定义多层嵌套的 for 循环。

守卫: for 表达式中,可以添加 if 判断语句,这个 if 判断就称之为守卫。我们可以使用守卫让 for 表达式更简洁。

语法

for(i <- 表达式/数组/集合 if 表达式) {
    // 表达式
}

示例: 使用 for 表达式打印 1-10 之间能够整除 3 的数字。

参考代码:

// 添加守卫,打印能够整除3的数字
scala> for(i <- 1 to 10 if i % 3 == 0) println(i)
3
6
9

for 推导式: 将来可以使用 for 推导式生成一个新的集合(一组数据)。在 for 循环体中,可以使用 yield 表达式构建出一个集合,我们把使用 yield 的 for 表达式称之为推导式。

示例: 生成一个 10、20、30…100 的集合。

参考代码:

// for推导式:for表达式中以yield开始,该for表达式会构建出一个集合
scala> val v = for(i <- 1 to 10) yield i * 10
v: scala.collection.immutable.IndexedSeq[Int] = Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

yield 推导式就是将循环的每一个返回值都收集起来,收集到一个集合中作为 for 循环的返回值。

1.5.2 while 循环

Scala 中 while 循环和 Java 中是一致的。

示例: 打印 1-10 的数字。

参考代码

scala> :paste
// Entering paste mode (ctrl-D to finish)
var i = 1
while(i <= 10){
 println(i)
 i += 1
}
// Exiting paste mode, now interpreting.
1
2
3
4
5
6
7
8
9
10
i: Int = 11
scala>

1.6 break 和 continue

在 Scala 中,类似 Java 和 C++ 的 break/continue 关键字被移除了。如果一定要使用 break/continue,就需要使用 scala.util.control 包的 Break 类的 breakablebreak 方法。

1.6.1 实现 break

用法

  1. 导入 Breaks 包 import scala.util.control.Breaks._
  2. 使用 breakable 将 for 表达式包起来。
  3. for表达式中需要退出循环的地方,添加 break() 方法调用。

示例: 使用 for 表达式打印 1-100 的数字,如果数字到达 50,退出 for 表达式。

参考代码

// 导入scala.util.control包下的Break
scala> import scala.util.control.Breaks._
import scala.util.control.Breaks._
scala> breakable{
     | for (i <- 1 to 100){
     |  if(i >= 50) break()
     |  else println(i)
     | }
     | }

1.6.2 实现 continue

用法: continue 的实现与 break 类似,但有一点不同:实现 break 是用 breakable{} 将整个 for 表达式包起来,而实现 continue 是用 breakable{} 将 for 表达式的循环体包含起来就可以了。

示例: 打印 1-100 的数字,使用 for 表达式来遍历,如果数字能整除10,不打印。

// 导入scala.util.control包下的Break    
scala> import scala.util.control.Breaks._
import scala.util.control.Breaks._
scala> for(i <- 1 to 100){
     | breakable{
     | if(i%10==0)break()
     | else println(i)
     | }
     | }

解答, 为何 break 功能要包住外面,continue 包住 for 循环体呢?因为,在这两种实现中,break 方法都是跳出了 breakable 包含的代码块,向下继续执行。唯一不同的是,如果 breakable 包住 for 循环,那么跳出的时候,就把 for 循环也跳出了,就向下继续执行了,就实现了类似 java 中 break 的功能。如果 breakable 包住 for 循环的循环体的话,那么跳出的时候,还在 for 循环内,只是当前这一次的循环体执行完成了,所以继续执行就是继续执行下一次的 for 循环。所以,包住的地方不同,实现的功能不同,但是对于 breakable 和 break 来说,他们的功能从未改变。

1.7 方法

一个类可以有自己的方法,Scala 中的方法和 Java 方法类似。但 Scala 与 Java 定义方法的语法是不一样的。

1.7.1 定义方法

语法

def methodName (参数名:参数类型, 参数名:参数类型) : [return type] = {
    // 方法体:一系列的代码
}
  1. 参数列表的参数类型不能省略(因为之前定义变量的时候可以省略,这里不要混淆了,因为变量给了初始值,可以根据初始值推断类型)。
  2. 返回值类型可以省略,由 Scala 编译器自动推断。
  3. 返回值可以不写 return,默认就是 {}块表达式的值。

示例:

  1. 定义一个方法,实现两个整形数值相加,返回相加后的结果。
  2. 调用该方法。

参考代码

scala> def add(a:Int, b:Int) = a + b
add: (a: Int, b: Int)Int
scala> add(5,6)
res4: Int = 11

1.7.2 返回值类型推断

Scala 定义方法可以省略返回值,由 Scala 自动推断返回值类型。这样方法定义后更加简洁。定义递归方法,不能省略返回值类型。因为,递归调用是一层一层向内走,当前那一层无法推断返回类型,会导致一系列问题。

示例: 定义递归方法(求阶乘),比如求 10 的阶乘,10 * 9 * 8 * 7 * 6 * ... * 1

参考代码

image.png

1.8 方法参数

Scala 中的方法参数,使用比较灵活。它支持以下几种类型的参数:默认参数、带名参数、变长参数。

1.8.1 默认参数

在定义方法时可以给参数定义一个默认值。

示例:

  1. 定义一个计算两个值相加的方法,这两个值默认为 0。
  2. 调用该方法,不传任何参数。

参考代码

// x,y带有默认值为0 
scala> def add(x:Int = 0, y:Int = 0) = x + y
add: (x: Int, y: Int)Int
scala> add()
res5: Int = 0

1.8.2 带名参数

在调用方法时,可以指定参数的名称来进行调用。

示例:

  1. 定义一个计算两个值相加的方法,这两个值默认为 0。
  2. 调用该方法,只设置第一个参数的值。

参考代码:

scala> def add(x:Int = 0, y:Int = 0) = x + y
add: (x: Int, y: Int)Int
scala> add(1)
res6: Int = 1

1.8.3 变长参数

如果方法的参数是不固定的,可以定义一个方法的参数是变长参数。语法格式如下:

def 方法名(参数名:参数类型*):返回值类型 = {
    方法体
}

在参数类型后面加一个 * 号,表示参数可以是0个或者多个。

示例:

  1. 定义一个计算若干个值相加的方法。
  2. 调用方法,传入以下数据:1,2,3,4,5。

参考代码:

scala> def add(num:Int*) = num.sum
add: (num: Int*)Int
scala> add(1,2,3,4,5)
res7: Int = 15

其他:Scala 允许指定最后一个参数是可变长度的,或者唯一一个参数。变长参数,在函数体内本质上是一个 Array 实例,也就是除了例子里面的 sum 外,我们也可以用 for 循环迭代它,如:

scala> def add(x:Int*): Int={
     | var result=0
     | for(i <- x) result += i
     | result
     | }
add: (x: Int*)Int
scala> add(1,2,3)
res8: Int = 6

虽然它本质上是一个 Array,但是你不可以将 Array 对象传递给它,如果要传递需要传递如 array:_* 表明将每个元素传递给它,而不是整个数组对象。如:

add(ar:_*)
相关文章
|
8天前
|
存储 Java API
java8新特性 lambda表达式、Stream、Optional
java8新特性 lambda表达式、Stream、Optional
|
8天前
|
Java
|
8月前
|
存储 Java C语言
Java SE 数据类型
Java中数据类型主要分为两类,而基本数据类型可分为四类八种
29 0
09-Groovy-数据类型-List介绍
09-Groovy-数据类型-List介绍
|
7月前
|
安全 Java
Java8中的Stream()与ParallelStream()的区别
Java8中的Stream()与ParallelStream()的区别
45 0
|
Scala 开发工具 流计算
Flink / Scala - java.lang.NumberFormatException: Not a version: 9
Flink V1.13.1 +Scala 2.11.8 提交任务后,报错Caused by: org.apache.flink.shaded.guava18.com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NumberFormatException: Not a version: 9 ,遂排查与解决。
277 0
Flink / Scala - java.lang.NumberFormatException: Not a version: 9
|
存储 分布式计算 Hadoop
HBase 是用 Java 编程语言
HBase 是用 Java 编程语言
338 0
|
Java Scala 开发者
ArrayBuffer 转 Java 的 List | 学习笔记
快速学习 ArrayBuffer 转 Java 的 List
311 0
|
Java 容器
【Java8新特性】- Optional应用
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
153 0
【Java8新特性】- Optional应用
|
Java 编译器 Scala
【Scala】Scala之Classes and Properties(一)
前面学习了控制结构,下面学习Scala的Class和Properties。
143 0
【Scala】Scala之Classes and Properties(一)

热门文章

最新文章