标签(空格分隔): hadoop scala
简介(来源快学scala)
scala是一个集对象和函数于一体是一门编程语言,但是实际上也有主次的,在scala中函数才是头等公民(贵族)。所以这一节我们主要是来学习函数和一些高阶的语法。
函数的用法与操作
作为值的函数
//函数作为值
val num = 3.15
import scala.math._
val fun = ceil _
fun(num)
如果我们用REPL我们会看到 num是一个Double 而fun是一个函数(Double)=> Double,这里说明两点 ceil后面的 _ 是干嘛滴,表示确实指的ceil这个函数,而不是忘记给人家传参了。第二点这里的fun是一个变量,包含了这个函数的变量,这里函数是作为一个值。
函数的用法:上方的fun(num)就是直接调用,另外我们也可以作为参数传递进去。比如
val newArr = Array(2.3,3.5,4.5).map(fun)
for(a <- newArr){
println(a)
}
上方就是将函数作为参数传递给map方法.
匿名函数&函数调用&高阶函数
匿名函数:
(x:Int ,y:Int) => x*y
通过REPL可以直接看到这是一个函数,因为这里没有给人家名字所以是匿名的。
函数做为一个函数的参数的写法:
def valueAtOneFunction(f:(Double)=> Double): Double = f(2.0)
#下面这个是调用
valueAtOneFunction((y:Double) => y* 5)
#通过这个 我们可以看到这个方法转换成函数的定义
val dFun = valueAtOneFunction _
(Double => Double) => Double 参数类型=>结果类型 就可以看出来了
如果一个函数以另一个函数作为参数则称这个函数为高阶函数,在快学scala中其实valueAtOneFuntion下面这种写法也叫高阶函数,让我对方法和函数有点头晕(暂且叫做方法吧因为不能直接作为参数被调用)。
def valueAtOneFunction(f:(Double)=> Double) = f(2.0)
说下高阶函数也可以(PS:是可以不是必然),产生另一个函数。比如
val hightFun = (x:Double) => (y:Double) => y*5*x
# 下面返回的是一个函数
val hightF = hightFun(5)
参数推断
如果已知函数的的参数类型,我们再做传参的时候scala会自行推断出参数的类型我们可以不写。
比如:
def valueAtOneFunction(f:(Double)=> Double) = f(2.0)
#因为scala已经知道推断类型了,所以我们可以省略参数类型
valueAtOneFunction((x) => 3 * x)
# 因为只有一个参数进一步省略
valueAtOneFunction( x => 3 * x)
# 因为参数x在之后只出现一次 所以可用_替换
valueAtOneFunction(3 * _)
# 但是如果是不是传给本身已知的参数类型这样写是不合法的
val fun = 3* _ # 错误滴
val fun = 3*(_:Double) # 正确滴
柯里化
柯里化是啥? 柯里化就是原先接收两个参数的方法或者函数,转换成接受一个参数的函数的过程。 而返回的新的函数是原先第二个参数作为参数的函数。来我们来看下如下代码。
#方法的写法
def curryM(x:Int) = (y:Int) => x*y
val cm1 = curryM1(2) #返回一个函数
#调用这个函数
cm1(3)
#函数的写法
val curryFun = (x:Int) => (y:Int) => x * y
val cf = curryFun(3) # 返回函数
下面来看一个Seq自带的柯里化函数
val a1 = Array("Hello","World")
val a2 = Array("hello","world")
val eqFun = (a:String,b:String) => a.equalsIgnoreCase(b)
a1.corresponds(a2)(eqFun) #corresponds是自带柯里化函数 第一个参数是Seq[B] 第二个参数是 前提条件函数 p:([A],[B]) => Boolean