【scala】匿名函数和闭包

函数的类型和值

Scala是一种纯面向对象的语言,每个值都是对象。Java是一种不全面向对象的语言。

Scala也是一种函数式语言,其函数也能当成值来使用。Java则是指令试编程。

但是Scala同时支持指令试编程和函数式编程,是两种编程方式的结合的一门语言。

在Scala中,我们可以把函数当作一个数据类型,可以像任何其他数据类型一样被传递和操作。这体现了函数式编程的核心。

我们可以像定义变量的那样去定义一个函数,因此,函数也就会和其他变量一样拥有类型和值。

我们看个例子

def counter( value:Int ) : Int = { value + 1 }

我们定义了一个counter函数,参数为Int类型的value,返回值为Int类型,大小为value+1。

counter函数的类型为  ( Int ) => Int 

箭头前,圆括号里面的为参数的类型,有多个参数依次写到圆括号中即可,(Int,String)。

当只有一个参数的时候可以省略圆括号 Int => Int

箭头后,为返回值类型

counter函数的值为(value) => { value + 1}

箭头前,圆括号里面的为参数的值,多个参数依次写到圆括号中即可。我们可以在这里定义参数类型,(value:Int)=>{value+1}

箭头后,大括号里面为返回的值,当只有一条语句的时候可以省略掉大括号。(value)=> value + 1

我们知道了函数的类型和值,试试定义一个函数变量。

val num : Int = 5;
//我们照着这个例子完成函数变量的定义
val counter :(Int)=> Int  = { (value) => {value+1} }

使用函数变量

println( counter(1) )

匿名函数

当一个函数就只用一次,我们就不需要给函数命名,这时我们就可以使用匿名函数。

我们通常把匿名函数称为“Lambda表达式”。

格式如下:(参数) => 表达式       //如果参数只有一个,圆括号可以省略

示例

(num:Int) =>  num*2

我们可以直接把匿名函数放到变量中

val myNum :(Int) => Int = (num:Int) => num *2   
//这里的形式和上面定义函数变量是一样的,只有一条语句的时候可以省略{}
//我们可以省略掉返回类型让语言自己判断,但是需要添加传入参数的类型
val myNum = (num:Int) => num*2   
println(myNum(1))  //使用函数变量

我们需要注意,虽然Scala语言有自动推断类型机制,但是我们不能全部省略,需要有部分类型确定才能推断出省略的部分类型。

闭包

闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。

val myNum = (num:Int) => num*2  //普通函数
val myNum = (num:Int) => num*a  //闭包,a为变量

我们看到闭包和普通函数的区别,闭包函数的返回值不仅根据参数num来确定,还依赖于外部的变量a

我们不能在没有定义变量a之前定义这个闭包,会提示not found value a。

正确定义闭包函数的方式

scala> var a = 10
a: Int = 10

scala> val myNum = (num:Int) => num*a   //定义闭包函数前依赖的变量必须有值
myNum: Int => Int = $$Lambda$1050/1792172929@4b20aa21

scala> myNum(10)
res2: Int = 100
scala> a = 20   //当我们修改外部的a的变量值,闭包函数的返回值也跟着变化,创建出一个新的闭包
a: Int = 20

scala> myNum(10)
res3: Int = 200

  

 

posted @ 2018-04-26 11:29  zzhangyuhang  阅读(2162)  评论(0编辑  收藏  举报