您的位置:首页 > 其它

scala 开发入门(4)-- 函数

2018-03-08 11:22 204 查看
标准的scala函数定义如下
def gcd(x:Int,y:Int):Int = {函数体} ,scala具有类推导的功能,会根据最终的返回值推导函数的返回类型,因此在实际应用中也常常会省略函数的返回值。
不过类推导有两个限制
(1)如果需要 return 关键字指定返回值,则必须显式的指定函数返回值的类型。

(2)如果函数中存在递归调用,则必须显式的指定函数返回值的类型

值函数

在scala中函数可以像变量一样赋值,把这种函数称为值函数,标准的值函数如下
val sum = (x:Int,y:Int) => println(x+y)

=> 称为函数映射符,意思是将左边的某种类型转换成右边的某种类型,注意值函数不能像普通函数那样指定其返回值类型,编译器会进行类型推导来确定函数的返回值类型。val sum = (x:Int,y:Int):Int => x+y //错误,值函数不能在参数后面指定返回值类型
val sum = (x:Int,y:Int) => x+y //正确

val f = (x:Double) => 2*x
f(10) //20.0值函数最常用的场景就是作为高阶函数的输入,可以简化val arrInt = Array(1,2,3,4) //定义一个定长数组
val increment = (x:Int) => x+1
arrInt.map(increment) //Array(2,3,4,5)

//简化
arrInt.map((x:Int) => x+1)
//x的类型可以通过类型推断得到,因此可以省略
arrInt.map((x) => x+1)
//只有一个参数,括号可以省略
arrInt.map(x => x+1)
//x => x+1 由于输入参数在函数映射符左右两边只出现一次,因此可以用占位符 '_' 对该值函数进行进一步的简化
arrInt.map(_+1)

高阶函数

//定义一个高阶函数,该函数的输入参数为函数类型 (Double) => Double
def higherOrderFunction(f:(Double) => Double) = f(100)
//定义一个函数,该函数类型就是 (Double) => Double
def sqrt(x:Double) = Math.sqrt(x)
//使用高阶函数
val x = higherOrderFunction(sqrt)   // x:Double = 10.0
高阶函数除能够将函数作为参数外,还可以将函数作为返回值//返回函数类型
def higherOrderFunction(factor:Int):Double => Double = {(x:Double) => factor * x}
//使用函数类型推导,不用指定返回类型
def higherOrderFunction(factor:Int) = (x:Double) => factor * x
//通过高阶函数生成值函数
val multiply = higherOrderFunction(100) //multiply = (x:Double) => 100*x
//使用值函数
multiply(10) //1000.0高阶函数的使用
map:将函数f应用于数组所有的元素,并返回一个新的数组。

flatMap:将函数f作用于集合中的所有元素,各元素得到相应的集合,然后再将其扁平化返回。
filter:返回所有能满足条件的元素集合
reduce:使用函数op作用于集合上,op为指定的联合二元算子。

fold:给定初始值,再使用联合二元操作算子对集合进行fold操作。

柯里化函数

在介绍高阶函数时,我们定义了一个返回值类型为函数类型的高阶函数。def higherOrderFunction(factor:Int) = (x:Double) => factor*x
//可以使用下列代码调用
higherOrderFunction(10)(50) //500.0higherOrderFunction(10)(50) 这种调用方式就与柯里化函数的调用方式十分相似。柯里化函数定义如下def multiply(factor:Int)(x:Double) = factor*x
multiply(10)(50) //500.0

//柯里化函数不是高阶函数,因此不能像higherOrderFuntion(10)这样使用返回一个函数对象
multiply(10) //错误用法

部分应用函数

前面说过,柯里化函数不能通过multiply(10)那样生成新的函数,但是可以通过部分应用函数生成。//multiply(10)_ 生成部分应用函数 pdf
val pdf = multiply(10)_
pdf:Double => Double = <function1>
//调用部分应用函数 pdf
pdf(50) //500.0

//可以两个参数都不指定
val pdf = multiply_
//像higherOrderFuntion 那样生成新的函数对象
val pdf2 = pdf(10) //pdf2:Double => Double = <function1>

偏函数

偏函数就是那些并非所有的变量域都有对应值域的函数//定义一个偏函数 isEven,只处理为偶数值的参数
val isEven:PartialFunction[Int,String] = {
case x if x%2 ==0 => x+"is Even"
}

//只能处理输入的偶数值
isEven(10)
res0:String = 10 is Even
isEven(11) //报错

//定义函数时使用 PartialFunction[Any,Unit] 修饰
def receive:PartialFunction[Any,Unit] = {
case x:Int => println("Int Type")
case x:String => println("String Type")
case _ => println("Other Type")
} //关于模式匹配后面会提及
等同于
val receive:PartialFunction[Any,Unit] = {
...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scala 函数