写点什么

Scala 语法特性 (二): 控制语句及函数方法

发布于: 2020 年 11 月 16 日
Scala语法特性(二):控制语句及函数方法

控制语句

Scala的条件和循环语句和大多数语言类似,不同的是Scala不支持break和continue语句,关于这一点Scala给的解释:

  • 多数情况下,continue和break是不必要的,可以用小函数更好地解决。

  • 在循环当中使用continue是非常容易理解的,但是在Scala的函数闭包中是难以解释的

  • 如果巧妙地使用函数字面量代替continue和break,可以使代码更加精简。

  • 开发人员表示可以以纯库函数的形式提供对两者的支持。



在Scala2.8版本之后提供了util.control.Breaks._库来使用break操作,下面计算从0到1000的数值之和,当和大于1000时,退出不再累加并打印出计算出的累计值。

package HelloScala
import util.control.Breaks._
object HelloScala {
def main(args: Array[String]): Unit = {
var sum = 0;
breakable{//循环外部,实现break
for (i <- 0 to 1000) {
sum += i;
if (sum >= 1000) break;
}
}
println(sum);
}
}



但是对于continue还是没有支持,可以通过类似下面的例子来实现,下面打印0到10中的奇数:

package HelloScala
import util.control.Breaks._
object HelloScala {
def main(): Unit = {
for (i <- 0 to 10) {
breakable {//循环内部,实现continue
if (i % 2 == 0) break
println(i)
}
}
}
}




补充于2020年11月30日

模式匹配

在C++、Java中Switch控制语句中case执行结束,需要添加break,否则会出现错误,在Scala中,通过模式匹配来解决这个问题。相关实现示例如下:

object HelloScala {
def main(args: Array[String]): Unit = {
for (i <- 0 to 100) {
i match {
case 10 => println(10);
case 50 => println(50);
case _ if(i % 3 == 0) => println(i + "可以被3整除");
case _ if(i % 7 == 0) => println(i + "可以被7整除");
case _ =>
}
}
}
}

执行结果:

0可以被3整除
3可以被3整除
6可以被3整除
7可以被7整除
9可以被3整除
10
12可以被3整除
14可以被7整除
15
18可以被3整除






函数和方法

在Scala中函数(Function)也是一个对象,借用函数式编程思想,函数可以作为参数传递给另外一个函数,而方法(Method)指类中定义的方法,属于类的一部分,不可以作为一个参数传入方法中。

  • 函数式一个完整的对象,本质上继承了Trait类的对象。

  • 使用val语句定义函数,使用def定义方法,方法名称后紧跟一个空格加下划线,可以将方法转换为函数,编译器会自动完成该操作。

def methodName([参数列表]):[return type] // 声明
def methodName([参数列表]):[return type] = {// 定义
method body
return [expr]
}



下面简单实现一个加法器

package HelloScala
class Test{
def m(x : Int, y : Int) : Int = { // 方法
x + y
}
val func = (x : Int, y : Int) => x + y // 函数
// 方法转函数
val func1 = func _
}
object HelloScala {
def main(args: Array[String]): Unit = {
val test = new Test();
println(test.m(2, 3));
}
}

可变参数列表

指在函数调用时灵活传入一个变长数组,在Scala中通过在类型之后加星号,将其设置为可变参数。只有函数最后一个参数可以设置为可重复的可变参数列表。

object HelloScala {
def main(args: Array[String]): Unit = {
def pringStringList(args : String*) = {
var i : Int = 0;
for (arg <- args) {
println("Arg value [" + i + "] = " + arg);
i = i + 1;
}
}
pringStringList("Scala", "Python", "C++", "C");
}
}

执行结果:

Arg value [0] = Scala
Arg value [1] = Python
Arg value [2] = C++
Arg value [3] = C



默认参数值

传入默认参数值和C++比较像,传入默认值之后相关参数可以不传递参数。下面实现一个对某个数字进行递增:

object HelloScala {
def main(args: Array[String]): Unit = {
def ascend(x : Int, y : Int = 1) : Int = {
return x + y;
}
println(ascend(5), ascend(5, 2))
}
}

执行结果:

(6,7)



偏应用函数

偏应用函数指的是,将方法当中的一个参数固定,然后重新声明为一个函数,是Scala的一种语法糖,在规模调用某个方法时,可以简化部分操作,同时方便对某一参数的修改。

import java.util.Date
object HelloScala {
def main(args: Array[String]): Unit = {
def log(date:Date, message: String): Unit = {
println(date + " : " + message);
}
val date = new Date();
val logWithDateBound = log(date, _:String)
logWithDateBound("message 1");
Thread.sleep(1000);
}
}



指定函数参数名

Scala支持通过指定函数参数名而无需按照顺序向函数传递参数。

def printInt(a:Int, b:Int): Unit ={
println("a: " + a + ", b: " + b);
}
printInt(b = 8, a = 16)

执行结果:

a: 16, b: 8



高阶函数

在Scala中,可以将函数作为参数或通过运算返回一个函数的引用,这种函数被称为高阶函数。

object HelloScala {
def layout[A](x : A) = "[ " + x.toString() + " ]";
def apply(f:Int => String, v:Int) = f(v)
def main(args: Array[String]): Unit = {
println(apply(layout, 18));
}
}



函数柯里化

函数柯里化指的是将原来接收两个参数的函数变成新的接收一个参数的函数的过程,新函数返回以原有第二个参数为参数的函数。

def add(x : Int) = (y : Int) => x + y
var res = add(5); //匿名函数
var sum : Int= res(7);



参考资料

  • 书籍《Spark Streaming 实时流式大数据处理实战》

  • https://blog.csdn.net/lovehuangjiaju/article/details/47176829

发布于: 2020 年 11 月 16 日阅读数: 26
用户头像

正向成长 2018.08.06 加入

想要坚定地做大规模数据处理(流数据方向),希望结合结合批处理的传统处理方式,以及之后流批混合处理方向进行学习和记录。

评论

发布
暂无评论
Scala语法特性(二):控制语句及函数方法