Scala编程第3版第七章(函数)
2020-03-12 18:56:36    55    0    0
yuziyue

函数内定义函数

和Python一样,也可以在函数内部定义新的函数,新函数的作用域只在当前函数有效

def calcSalary() = {
    def getSalary() = {
        10000
    }
    getSalary * 1.1
}

println(calcSalary)

函数作为参数

val n = List(-11, -10, -5, 0, 5, 10)

// 返回大于 0 的数据
n.filter((x: Int) => x > 0)

// 返回大于 0 的数据
n.filter((x) => x > 0)

// 返回大于 0 的数据:效果同上,简写版本
n.filter(_ > 0)

// 简版的函数定义,这里的待填空下划线必须给定类型,否则报错。
val f=(_: Int) + (_: Int)
f(3,4)
res4: Int = 7

部分应用函数

部分应用函数,简单的来说,其实就是先给函数提前确定一些参数的值,这样一来就形成了新的函数,新函数里面会去调用原来的函数,传入原来格式的参数。

// 当你这样使用下画线时,实际上是在编写一个部分应用的函数(partially applied function)。在Scala中,当你调用某个函数,传入任何需要的参数时,你实际上是应用那个函数到这些参数上
val n = List(-11, -10, -5, 0, 5, 10)
n.foreach(println _)

// 部分应用的函数是一个表达式,在这个表达式中,并不给出函数需要的所有参数,而是给出部分,或完全不给。举例来说,要基于 sum创建一个部分应用的函数,假如你不想给出三个参数中的任何一个,可以在"sum"之后放一个下画线。这将返回一个函数,可以被存放到变量中。
def sum(a: Int, b: Int, c: Int) = a + b + c
val a = sum _
a(1, 2, 3)
res1: Int = 6

// 背后发生的事情是:名为a的变量指向一个函数值对象。这个函数值是一个从Scala编译器自动从sum _ 这个部分应用函数表达式生成的类的实例。由编译器生成的这个类有一个接收三个参数的apply方法。生成的类的apply方法之所以接收三个参数,是因为表达式sum _缺失的参数个数为3。Scala编译器将表达式a(1, 2, 3)翻译成对函数值的apply方法的调用,传入这三个参数1、2和3。因此,a(1,2,)可以被看作是a.apply(1,2,3)的简写形式。

部分应用函数之所以叫作部分应用函数,是因为你并没有把那个函数应用到所有入参。拿sum _来说,你没有应用任何入参。不过,完全可以通过给出一些必填的参数来表达一个部分应用的函数,比如

val b = sum(1, _: Int, 3)
b: Int => Int = $$Lambda$796/914175168@4ce25e47
b(5)
res2: Int = 9

 

可变参数列表

要表示这样一个重复参数,需要在参数的类型之后加上一个星号(*)。在函数内部,这个重复参数的类型是一个所声明的参数类型的Array。因此,在echo函数内部,args的类型其实是Array[String]。

// 这样定义以后,echo可以用到零到多个String参数调用
def echo(args: String*) = for (arg <- args) println(arg)

// 尽管如此,如果你有一个合适类型的数组,并尝试将它作为重复参数传入时,你将得到一个编译错误
var arr = Array("What", "are", "you", "doing?")
echo(arr)

// 要完成这样的操作,你需要在数组实参的后面加上冒号和一个_*符号
echo(arr: _*)

 

带默认值的命名参数

带名字的参数让你可以用不同的顺序将参数传给函数。其语法是简单地在每个实参前加上参数名和等号。位置参数在前,其他的命名参数可以随意调换位置。

def goto_classroom(datetime: String, address: String="room1", username: String="yourself") = {
    println(datetime, address, username)
}

goto_classroom("now")
(now,room1,yourself)

goto_classroom("now", username="xiaohong", address="bju")
(now,bju,xiaohong)

 

 

上一篇: Spark快速上手

下一篇: Bash解析命令行参数

55 人读过
文档导航