暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Scala函数式编程(三)——值函数的简化

Scala学习 2016-05-31
195

值函数最常用的场景是作为高阶函数的输入,假设定义了如下整型数组:


scala> val arrInt=Array(1,2,3,4)

arrInt: Array[Int] = Array(1, 2, 3, 4)


现在希望能够将数组中所有的元素加1,可以通过Array提供的map方法来处理,map方法的定义如下所示。


def map[B](f: (A) ⇒ B):Array[B]


该方法使用了泛型,泛型B指的是数组最终返回的元素类型,f表示作用于数组各元素上的函数,(A) ⇒ B为函数的类型,表示的是该函数的输入参数类型为A,返回值类型为B。这里我们定义如下值函数作为map函数的输入。


scala> val increment=(x:Int)=>x+1

increment: Int => Int = <function1>


使用时直接将变量increment作为函数的参数使用。


scala> arrInt.map(increment)

res0: Array[Int] = Array(2, 3, 4, 5)


在实际使用时,如果值函数只使用一次,则常常直接作为函数参数。


scala> arrInt.map((x:Int)=>x+1)

res1: Array[Int] = Array(2, 3, 4, 5)


在实际使用时,值函数还可以对其进行简化,对于代码arrInt.map((x:Int)=>x+1),由于arrInt为整型数组,因此传入map的函数输入类型可以通过类型推断得到,arrInt.map((x:Int)=>x+1)可以简写为以下所示。


//值函数省略参数类型,参数类型通过类型推断得到

scala> arrInt.map((x)=>x+1)

res2: Array[Int] = Array(2, 3, 4, 5)


arrInt.map((x)=>x+1)中的值函数(x)=>x+1参数只有一个,在这种条件下,可以将值函数输入参数的括号去掉。


//值函数参数只有一个时,可以省略括号

scala> arrInt.map(x=>x+1)

res3: Array[Int] = Array(2, 3, 4, 5)


代码arrInt.map(x=>x+1)中的值函数x=>x+1输入参数在符号=>右边只出现一次,此时可以用占位符对该值函数进行进一步简化。


//值函数参数在=>右边只出现一次时,可以用占位符_对函数进行简化

scala> arrInt.map(_+1)

res4: Array[Int] = Array(2, 3, 4, 5)


需要特别注意的是,代码arrInt.map(_+1)合法是因为arrIntInt类型的数组,可以进行类型推断,但如果将_+1赋值给变量时会出错。


scala> val increment=1+_

<console>:7: error: missing parameter typefor expanded function ((x$1) => 1.+(x$1))

       valincrement=1+_

                       ^

 

scala> val increment=_+1

<console>:7: error: missing parameter typefor expanded function ((x$1) => x$1.$plus(1))

       valincrement=_+1

                      ^

不管是val increment=1+_还是val increment=_+1,其出错原因是编译器无法进行类型推断的,虽然代码中有+11+这种表达式,但它不足以让编译器知道确定的类型,因为无论是1+字符串类型还是字符串类型+11+Double类型还是Double类型+1等都是合法的。要合法使用上面的代码,需要明确指定类型。



//明确指定类型

scala> val increment=(_:Int)+1

increment: Int => Int = <function1>

 

scala> val increment=1+(_:Int)

increment: Int => Int = <function1>


还有一种方式,是指定increment的具体类型。



//指定increment的参数类型为(Int)=>Int,即函数的输入参数为Int类型,返回值的类型为Int

scala> val increment:(Int)=>Int=1+_

increment: Int => Int = <function1>


文章转载自Scala学习,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论