Scala入门到精通——第五节 函数与闭包

本节主要内容

(一)函数字面量(值函数)

(二)匿名函数

(三)函数的简化

(四)函数参数

(四)闭包

函数字面量(值函数)

函数字面量(function literal),也称值函数(function values),指的是函数可以赋值给变量。

一般函数具有如下形式:

而函数字面量具有如下形式:

/*
   函数字面量 function literal
   =>左侧的表示输入,右侧表示转换操作
*/
scala> val increase=(x:Int)=>x+1
increase: Int => Int = <function1>

scala> println(increase(10))
11
//前面的语句等同于
scala>  def increaseAnother(x:Int)=x+1
increaseAnother: (x: Int)Int

scala> println(increaseAnother(10))
11

    //多个语句则使用{}
val increase2=(x:Int)=>{
      println("Xue")
      println("Tu")
      println("Wu")
      println("You")
      x+1
}
scala>println(increase2(10))
Xue
Tu
Wu
You
11

//数组的map方法中调用(写法1)
scala> println(Array(1,2,3,4).map(increase).mkString(","))
2,3,4,5

匿名函数

//匿名函数写法(写法2)
scala>println(Array(1,2,3,4).map((x:Int)=>x+1).mkString(","))
2,3,4,5

函数进一步简化


//花括方式(写法3)
scala> Array(1,2,3,4).map{(x:Int)=>x+1}.mkString(",")
res25: String = 2,3,4,5

//省略.的方式(写法4)
scala> Array(1,2,3,4) map{(x:Int)=>x+1} mkString(",")
res26: String = 2,3,4,5

//参数类型推断写法(写法5)
scala> Array(1,2,3,4) map{(x)=>x+1} mkString(",")
res27: String = 2,3,4,5

//函数只有一个参数的话,可以省略()(写法6)
scala> Array(1,2,3,4) map{x=>x+1} mkString(",")
res28: String = 2,3,4,5

//如果参数右边只出现一次,则可以进一步简化(写法7)
scala> Array(1,2,3,4) map{_+1} mkString(",")
res29: String = 2,3,4,5

 //值函数简化方式
 //val fun0=1+_,该定义方式不合法,因为无法进行类型推断
scala> val fun0=1+_
<console>:10: error: missing parameter type for expanded function ((x$1) => 1
x$1))

//值函数简化方式(正确方式)
scala>  val fun1=1+(_:Double)
un1: Double => Double = <function1>

scala> fun1(999)
es30: Double = 1000.0

//值函数简化方式(正确方式2)
scala> val fun2:(Double)=>Double=1+_
fun2: Double => Double = <function1>

scala> fun2(200)
res31: Double = 201.0

函数参数

//函数参数(高阶函数)
//((Int)=>String)=>String
scala> def convertIntToString(f:(Int)=>String)=f(4)
convertIntToString: (f: Int => String)String

scala> convertIntToString((x:Int)=>x+" s")
res32: String = 4 s

//高阶函数可以产生新的函数
//(Double)=>((Double)=>Double)
scala>  def multiplyBy(factor:Double)=(x:Double)=>factor*x
multiplyBy: (factor: Double)Double => Double

scala> val x=multiplyBy(10)
x: Double => Double = <function1>

scala> x(50)
res33: Double = 500.0   

函数闭包

 //闭包(Closure)

//(x:Int)=>x+more,这里面的more是一个自由变量(Free Variable),more是一个没有给定含义的不定变量
//而x则的类型确定、值在函数调用的时候被赋值,称这种变量为绑定变量(Bound Variable)
scala> (x:Int)=>x+more
<console>:8: error: not found: value more
              (x:Int)=>x+more
                         ^
scala> var more=1
more: Int = 1

scala>val fun=(x:Int)=>x+more
fun: Int => Int = <function1>

scala> fun(10)
res1: Int = 11

scala> more=10
more: Int = 10

scala> fun(10)
res2: Int = 20

 //像这种运行时确定more类型及值的函数称为闭包,more是个自由变量,在运行时其值和类型得以确定
 //这是一个由开放(free)到封闭的过程,因此称为闭包

scala> val someNumbers = List(-11, -10, -5, 0, 5, 10)
someNumbers: List[Int] = List(-11, -10, -5, 0, 5, 10)

scala>  var sum = 0
sum: Int = 0

scala>  someNumbers.foreach(sum += _)

scala> sum
res8: Int = -11

scala>  someNumbers.foreach(sum += _)

scala> sum
res10: Int = -22

//下列函数也是一种闭包,因为在运行时其值才得以确定
def multiplyBy(factor:Double)=(x:Double)=>factor*x

添加公众微信号,可以了解更多最新Spark、Scala相关技术资讯

时间: 2024-09-17 11:54:00

Scala入门到精通——第五节 函数与闭包的相关文章

Scala入门到精通——第二十一节 类型参数(三)-协变与逆变

作者:摇摆少年梦 视频地址:http://www.xuetuwuyou.com/course/12 本节主要内容 协变 逆变 类型通匹符 1. 协变 协变定义形式如:trait List[+T] {} .当类型S是类型A的子类型时,则List[S]也可以认为是List[A}的子类型,即List[S]可以泛化为List[A].也就是被参数化类型的泛化方向与参数类型的方向是一致的,所以称为协变(covariance). 图1 协变示意图 为方便大家理解,我们先分析java语言中为什么不存在协变及下一

Scala入门到精通——第二十节 类型参数(二)

本节主要内容 Ordering与Ordered特质 上下文界定(Context Bound) 多重界定 类型约束 1. Ordering与Ordered特质 在介绍上下文界定之前,我们对scala中的Ordering与Ordered之间的关联与区别进行讲解,先看Ordering.Ordered的类继承层次体系: 通过上面两个图可以看到,Ordering混入了java中的Comparator接口,而Ordered混入了java的Comparable接口,我们知道java中的Comparator是一

Scala入门到精通——第六节:类和对象(一)

本节主要内容 1 类定义.创建对象 2 主构造器 3 辅助构造器 类定义.创建对象 //采用关键字class定义 class Person { //类成员必须初始化,否则会报错 //这里定义的是一个公有成员 var name:String=null } Person类在编译后会生成Person.class文件 利用javap -prviate Person命令查看字节码文件内容,可以看得到以下内容 D:\ScalaWorkspace\ScalaChapter06\bin\cn\scala\xtw

Scala入门到精通——第十节 Scala类层次结构、Traits初步

本节主要内容 Scala类层次结构总览 Scala中原生类型的实现方式解析 Nothing.Null类型解析 Traits简介 Traits几种不同使用方式 1 Scala类层次结构 Scala中的类层次结构图如下: 来源:Programming in Scala 从上面的类层次结构图中可以看到,处于继承层次最顶层的是Any类,它是scala继承的根类,scala中所有的类都是它的子类 Any类中定义了下面几个方法: //==与!=被声明为final,它们不能被子类重写 final def ==

Scala入门到精通——第七节:类和对象(二)

本节主要内容 单例对象 伴生对象与伴生类 apply方法 应用程序对象 抽象类 单例对象 在某些应用场景下,我们可能不需要创建对象,而是想直接调用方法,但是Scala语言并不支持静态成员,Scala通过单例对象来解决该问题.单例对象的创建方式如下: object Student { private var studentNo:Int=0; def uniqueStudentNo()={ studentNo+=1 studentNo } def main(args: Array[String]):

Scala入门到精通——第四节 Set、Map、Tuple、队列操作实战

本节主要内容 mutable.immutable集合 Set操作实战 Map操作实战 Tuple操作实战 队列操作实战 栈操作实战 mutable.immutable集合 以下内容来源于scala官方文档: http://www.scala-lang.org/docu/files/collections-api/collections.html Scala collections systematically distinguish between mutable and immutable c

Scala入门到精通——第二十七节 Scala操纵XML

本节主要内容 XML 字面量 XML内容提取 XML对象序列化及反序列化 XML文件读取与保存 XML模式匹配 1. XML 字面量 XML是一种非常重要的半结构化数据表示方式,目前大量的应用依赖于XML,这些应用或利用XML作为数据交换格式,或利用XML进行文件配置等.像JAVA.C++及其它流行的程序开发语言都是依赖于第三方库来实现XML的操作,例如JAVA经常通过JDOM,DOM4J等XML处理工具进行XML的操纵,但Scala提供了对XML的原生支持,通过scala.xml._包下的类或

Scala入门到精通——第十一节 Trait进阶

本节主要内容 trait构造顺序 trait与类的比较 提前定义与懒加载 trait扩展类 self type 1 trait构造顺序 在前一讲当中我们提到,对于不存在具体实现及字段的trait,它最终生成的字节码文件反编译后是等同于java中的接口,而对于存在具体实现及字段的trait,其字节码文件反编译后得到的java中的抽象类,它有着scala语言自己的实现方式.因此,对于trait它也有自己的构造器,trait的构造器由字段的初始化和其它trait体中的语句构成,下面是其代码演示: pa

Scala入门到精通——第十三节 高阶函数

本节主要内容 高阶函数简介 Scala中的常用高阶函数 SAM转换 函数柯里化 部分应用函数 1. 高阶函数简介 高阶函数主要有两种:一种是将一个函数当做另外一个函数的参数(即函数参数):另外一种是返回值是函数的函数.这两种在本教程的第五节 函数与闭包中已经有所涉及,这里简单地回顾一下: (1)函数参数 //函数参数,即传入另一个函数的参数是函数 //((Int)=>String)=>String scala> def convertIntToString(f:(Int)=>Str