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

函数的赋值给变量

scala> def fun1(name : String){println(name)}

//fun1为函数的名称,(name:String)参数 Unit是返回值为Unit

fun1: (name: String)Unit

//现在将函数赋值给变量

//val fun1_v = fun1 _   //函数名 _   中间一定要加空格

//这时候的fun1_v就是函数了

scala> val fun1_v = fun1 _   //fun1 _ 此时就表示函数本身了

//此时我们看出fun1_v就是函数了,参数的类型是String类型,返回值是Unit

//  =>   是将左边的参数进行右边的加工。

fun1_v: String => Unit = <function1>

    scala> fun1("Spark")

Spark

 

scala> fun1_v("Spark")

Spark

 

scala> fun1_v("Scala")

Scala

 

匿名函数

在实际工作的时候,比如算法设计我们可能不需要函数名称,只需要函数执行的功能就可以了,这时候我们就会使用匿名函数。

但是我们要使用它,就可以借助函数赋值给变量,变量就变成了函数的性质,将匿名函数赋值给变量。

匿名函数的定义规则:

(参数 :类型=> 函数的操作

scala> val fun2 = (content : String) => println(content)

fun2: String => Unit = <function1>

 

scala> fun2("Hadoop")

hadoop

 

 

高阶函数

函数的参数也是函数,为啥可以?因为前面谈到了函数可以赋值给变量,而我们现在直接把函数作为函数的参数,也应该是可以的。这样的设计非常强大:

例如:我们使用函数去操作集合,可能需要循环遍历集合,这个时候我们就可以使用函数参数,而此时的函数参数具有遍历集合的功能。

 

//第一个参数,定义了一个函数,func是函数的名称,(String)是变量的类型,=>Unit指定函数的返回值是Unit

//第一个传入参数的要求是: 定义一个函数,函数值是Unit

scala> val hiScala = (content : String) => println(content)

hiScala: String => Unit = <function1>

 

scala> def bigData(func : (String) => Unit,content:String){func(content)}

bigData: (func: String => Unit, content: String)Unit

 

//传入的第一个参数是一个函数,传入第二个参数的时候,content就会作为参数传入//第一个hiScala函数里面

scala> bigData(hiScala,"Spark")

Spark

 

//item => (2*item) 是一个匿名函数,作为参数传入到map()函数中,map函数的作用是循环遍历集合中的所有元素。

scala> array.map(item => (2*item))

res5: Array[Int] = Array(2, 4, 6, 8, 10, 12, 14, 16, 18)

另外,高阶函数的返回值也有可能是函数

scala> def func_Returned(content : String) = (message : String) => println(message)

// 匿名函数本身是返回值,所有返回类型是Unitfunc_returned()函数的返回值类型// String.

func_Returned: (content: String)String => Unit 

 

scala> func_Returned("Spark")

//执行结果是一个函数

//输入类型是字符串String,为啥呢?因为 (message : String) 输入参数是String,返回类//型是Unit,因为println(message)是一条打印语句。

res7: String => Unit = <function1>

 

scala> def func_Returned(content : String) = (message : String) => println(content + " " + message)

func_Returned: (content: String)String => Unit

 

scala> val returned = func_Returned("Spark")

returned: String => Unit = <function1>

 

//为啥会打印 Spark 此时的Spark是上面def func_Returned(content : String) = //(message : String) => println(content + " " + message)为参数的输入值

//为啥会打印Scala 因为returned = func_Returned("Spark"),是把函数的返回值为函数//的返回值赋值给了returned,也就相当于把(message : String) => println(content + " " + //message) 赋值给了returned,此时我们传入参数,也就是message的参数,content//之前传过了。

 

scala> returned("Scala")

Spark  Scala

高阶函数的两个层面:

1.  函数的参数是函数

2.  函数的返回值是函数

高阶函数有一个重要的性质就是类型推断,可以自动推断出具体的参数和类型,并且对于只有一个参数的函数,可以声明掉小括号,如果在函数的函数体中,只使用一次输入参数的参数值的话,那么可以将函数的输入参数的名称省略,用下划线来代替。





闭包是函数,它的返回值取决于此函数之外声明一个或多个变量的值。

 假设,我们想写一个函数 f(x) ,该函数的返回值取决于变量 i 。伪代码为 

1
f(x)  =  x + i

我们尝试着写写这个函数

1
2
3
scala>  def  f(x  :  Int)  =  x + i
<console> : 10 :  error :  not found :  value i
        def  f(x  :  Int)  =  x + i

很明显,i 没有声明,那么能不能先声明变量i,再定义函数呢?

在scala中,定义一个变量,必须初始化。

1
2
3
4
scala>  var  :  Int
<console> : 10 :  error :  only classes can have declared but undefined members
(Note that variables need to be initialized to be defined)
        var  :  Int


一旦初始化了,那么上面的函数也就不依赖于变量i了。

scala中提供了如下的写法

1
def  f(x : Int)  =  (i  :  Int)  = > (x+i)

此时函数就依赖于i,并且i的值是未知的。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
object  ClosureOps {
     def  main(args :  Array[String]) :  Unit  =  {
           
       def  f(x : Int)  =  (i  :  Int)  = > (x+i)
       val  =  f( 1 )
       val  =  f( 2 )
       println(a( 10 ))
       println(b( 20 ))
       
     }
}


即函数值若想被创建必须捕获i的值,这一过程可以被理解为做对函数执行“关闭”操作,所以叫闭包。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值