Scala中function的理解

在函数式语言中,函数是和value同样地位的一等公民,他能够做为变量,或者做为参数传递给另外一个函数数组

##做为变量
val f=(x:Int)=>x+1
为啥能够这样写?
因为scala是OOP,因此function也是个object。各个function都是继承了Function类,好比Function1类表示参数是1的function类。
 
可见上述f是一个Function1的实例。因此做为实例的f有Function1的全部方法,其中有一个是apply方法,就是当f(1)的时候就会自动调用Function1的x+1这个方法。
这个时候怎么又来了个方法(method),函数和方法的区别是什么?
###function 和method的区别
能够说函数(function)是class,而method就是class中的一个函数(这个函数是指Java上的概念)。为啥呢,上面说了,各个function都是从Function继承过来的,那么每一个function都有一个特定的method,这个method是啥呢,就是能体现这个function真正做用的method,好比上面的就是x+1,只不过被Function类用apply包装了。咱们能够 想象成:
object myFunction extends Function1(){
    ...
    apply(x:Int):Int=x+1
    ...
}
那么val f=(x:Int)=>x+1其实就是val f=new myFunction()
因此f(1)=f.apply(1)
因此,结论就是,函数的概念是大于方法的,函数其实本质是class,他是包含了方法的。
因此在理解了Function实际上是class后,能很好的理解函数为何能够做为变量了,其实f就是这个Function的一个实例而已。
###关于Function与method的转换
method转为Function
定义了一个g方法,那么如何将方法转为函数呢
能够经过_来实现
val h=g _
这样h就成了一个实例了。
>关于下划线_的做用
  1. 做为“通配符”,相似Java中的*。如import scala.math._
  2. :_*做为一个总体,告诉编译器你但愿将某个参数看成参数序列处理!例如val s = sum(1 to 5:_*)就是将1 to 5看成参数序列处理。
  3. 指代一个集合中的每一个元素。例如咱们要在一个Array a中筛出偶数,并乘以2,能够用如下办法:a.filter(_%2==0).map(2*_)。
  又如要对缓冲数组ArrayBuffer b排序,能够这样:
  val bSorted = b.sorted(_
  4. 在元组中,能够用方法_1, _2, _3访问组员。如a._2。其中句点能够用空格替代。 
  5. 使用模式匹配能够用来获取元组的组员,例如
  val (first, second, third) = t
  但若是不是全部的部件都须要,那么能够在不须要的部件位置上使用_。好比上一例中val (first, second, _) = t
  6. 还有一点,下划线_表明的是某一类型的默认值。
  对于Int来讲,它是0。
  对于Double来讲,它是0.0
  对于引用类型,它是null。
  7.  用于将方法转换成函数,好比val f=sqrt _,之后直接调用f(250)就能求平方根了
 
##做为参数传递
定义了一个fun方法,里面的参数有两个一个是int型的x,一个是参数为int,返回值是int类型的函数f(感受和C语言中的函数指针有点像)
那么如何往里面传值呢,其实这里传的仍是一个变量,只是这个变量是Function的实例。上面分析了method能够转换为Function,因此这里至少有两种方法。
1. 直接传一个变量,好比val m=(x:Int)=>x+1
接着
2. 传一个方法(固然这个方法的参数和返回值须要知足上述条件)
接着
这个能成功运行,说明这里有一个隐性的转换机制。
 
>=>的做用
在Function中,表示将左边的转为右边的
val triple=(x:Double)=>3*x
将函数做为参数
def fun(f:(Double)=>Double)=f(0.25)
这里表示fun函数接受一个f函数做为参数,这里的f类型是(Double)=>Double表示输入为Double,输出为Double的函数
相关文章
相关标签/搜索