scala 自学笔记 高阶函数
2015-02-17 11:15
295 查看
作为值得函数
匿名函数
带函数参数的函数
参数(类型)推断
一些常见的高阶函数
闭包
SAM转换
柯里化
无参函数作为参数的简化写法(漂亮写法,没有这些功能也能写,就是很丑而已)
变量中可以存放函数 import scala.math._ val num = 3.14 // Double val fun = ceil _ // (Double) => Double, fun设为ceil函数, _ 意味着确实指这个函数,而不是碰巧忘记参数。 从技术上讲,_ 将ceil方法转成了函数,在scala中,无法直接操纵方法,而只能直接操纵函数。 fun(num) // 4.0 调用他 Array(3.14,1.42,2.0).map(fun) // Array(4.0,2.0,2.0) 传递他
匿名函数
(x: Double) => 3* x val triple = (x: Double) => 3 * x 这就跟用def一样 def triple(x: Double) => 3 * x Array(3.14, 1.42, 2.0).map((x:Double)=>3*x) // 直接把匿名函数 传递给另一个函数 另一种写法,将函数参数包在花括号 而不是圆括号中 Array(3.14, 1.42, 2.0) map {(x:Double) => 3*x} // 没有句点, 使用中置表示法
带函数参数的函数
def valueAtOneQuarter(f: (Double) => Double) = f(0.25) valueAtOneQuarter(ceil _) //1.0 valueAtOneQuarter(sqrt _) //0.5 valueAtOneQuarter的类型为 ( (Double) =>Double) => Double 这种接受函数参数的 函数, 称之为 高阶函数。 高阶函数 也可以产出另一个函数, def mulBy( factor: Double) = (x : Double) => factor * x val quintuple = mulBy(5) quintuple(20) // 100 mulBy类型 (Double) = > ( (Double) => Double )
参数(类型)推断
valueAtOneQuarter((x:Double) => 3 * x) // 0.75 由于valueAtOneQuarter知道会传入一个类型为(Double) = > Double的函数,所以可以简写: valueAtOneQuarter((x) = > 3 * x) valueAtOneQuarter( x = > 3 *x) // 当只有一个参数的函数,可以略去参数外围的() valueAtOneQuarter(3 * _) //如果参数在=>右侧只出现一次,可以用 _ 替换它 这些简写方式仅在参数类型已知的情况下才有效: val fun = 3 * _ //错误, 无法推断出类型 val fun = 3 * _(_:Double) // OK val fun:(Double) => Double = 3* _ //OK,因为给出了fun的类型
一些常见的高阶函数
(1 to 9).map("*" * _).foreach(prinlnt _) (1 to 9).filter(_ % 2 ==0) // 2,4,6,8 reduceLeft方法接受一个二元的函数,即一个带有两个参数的函数,并将它应用到序列中的所有元素,从左到右 (1 to 9).reduceLeft( _ * _) 等同于 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 更严格地说是 (...((1 *2) *3) * ... * 9 ) 排序 "Marry has a little lamb".split(" ").sortWith(_.length < _.length) 输出以个长度递增排序的数组:Array("a","had","Mary","lamb","little")
闭包
def mulBy(factor :Double) = (x: Double) => factor * x val triple = mulBy(3) val half = mulBy(0.5) triple(14) + " " + half(14) // 42 17 triple 和 half 都有自己的factor设置 这样一个函数被称为闭包, 闭包由代码和代码用到的任何非局部变量定义构成。
SAM转换
在Java中,不支持函数作为参数传递,当要告诉另一个函数做某件事时,通常做法是蒋动作放在一个实现某接口的累中,然后将该类的一个实例传递给另一个方法 很都时候,这些接口都只有单个抽象方法。在Java中被称为SAM类型 var counter = 0 val button = new JButton("Increment") button.addActionListener(new ActionListener{ override def actionPerformed(event: ActionEvent){ counter +=1 } }) 那么多样板代码,只为了执行一句 counter+=1。 如果我们提供一个隐式转换,就可以做只传一个函数给addActionListener,如: button.addActionListener((event: ActionEvent) => counter +=1 ) 隐式转换的声明: implicit def makAction(action:(ActionEvent) => Unit) = new ActionListener{ override def actionPerformed(event: ActionEvent){ action(event)} } 只需把这个函数和上面的代码放一起,就可以在所有预期ActionListener对象的地方传入任何(ActionEvent) => Unit 函数了.
柯里化
def mulOneAtATime(x:Int) = (y:Int) => x * y mulOneAtATime(6)(7) Scala 支持如下简写来定义这样的函数: def mulOneAtATime(x:Int)(y:Int) = x * y。 这看似和直接定义两个参数,没有分别 def mulOneAtATime(x:Int, y:Int) = x * y。 但在Scala中有很实际的用途,有时候,需要柯里化来把某个函数的参数单独拿出来,以提供更多用于类型推断的信息。 val a = Array("Hello","World") val b = Array("Hello","World") a.corresponds(b)(_.equalsIgnoreCase(_)) 这里,在API中 def corresponds[B](that: Seq[B])(p:(A,B) = >Boolean) : Boolean 这里, 类型推断其可以分析出 B 出自that的类型,利用这个信息来分析作为参数p传入的函数。 如,that是一个String类型的序列,那么久可以计算出p 的类型为(String, String) => Boolean。 然后编译时可以接受 _.equalsIgnoreCase(_)作为 (a:String, b:String)=>a.equalsIgnoreCase(b)的简写了
无参函数作为参数的简化写法(漂亮写法,没有这些功能也能写,就是很丑而已)
def runInThread(block : () => Unit){ new Thread{ override def run(){ block()} }.start() } runInThread { () => println("Hi")} //比较难看 简化,省去参数声明和调用该函数的() def runInThread(block : => Unit){ // 省去(),俗称 换名调用参数。 new Thread{ override def run(){ block} // 省去() }.start() } runInThread { println("Hi")} //看上去更自然。 结合柯里化的样例: def until(condition: =>Boolean)(block: => Unit){ if(condition){ block until(condition)(block) } } 调用: var x = 10 until (x==0){ x -=1 println(x) }// 完全像是在使用whili语句那样的函数。 如果没有柯里化的话: until ( x==0,{...}) , 就难看很多了
相关文章推荐
- scala学习笔记:高阶函数
- Scala 自学笔记3_特质
- scala学习笔记-高阶函数
- Scala 自学笔记
- [Scala]Scala学习笔记八 高阶函数
- scala 学习笔记 --高阶函数
- Python自学笔记之函数式编程1——高阶函数
- Scala 自学笔记 注解
- Scala自学笔记
- scala自学笔记(1)
- Scala 自学笔记2_类
- Scala 自学笔记 模式匹配和样例类
- scala学习笔记--高阶函数
- Scala自学代码笔记
- 快学Scala学习笔记及习题解答(12-14高阶函数、集合、模式匹配和样例类)
- Scala 学习笔记(六)------定义高阶函数
- Scala 自学笔记 集合
- scala学习笔记13 高阶函数
- scala学习笔记:高阶函数
- Scala 自学笔记 操作符