Scala基础知识笔记3-函数
object ScalaFunction { def main(args: Array[String]): Unit = { // 1 将函数赋值给变量时, 必须在函数后面增加 空格和下划线 var zmHello = sayHello _ zmHello("zm") // 使用变量调用函数 /** * 2 匿名函数 * 2.1 将匿名函数赋值给变量 (参数名: 参数类型) => 函数体 * 2.2 将匿名函数传入其他函数中 * */ var saySome = (name:String) => {println("hello niming " + name)} // 实现 2.1的效果 saySome("zm") /** * 功能1: 调用高阶函数 * 高阶函数 : 接收其他函数作为参数的函数 * 参数1表示接收的是一个函数,函数参数是string类型,返回值是Unit * 参数2表示参数是string类型 * 函数体是调用参数1的函数,同时参数1的函数的参数是高级函数参数2 */ def higherOrderFun(func:String =>Unit,name:String) { func(name) } higherOrderFun(saySome,"higher fun zm") // hello niming higher fun zm var saySome1 = (name:String,age:Int) => {println("higher fun1: hello: " + name + " the age is " + age )} // 定义普通函数 def higherOrderFun1(func:(String,Int)=>Unit,name:String,age:Int): Unit = { // 定义高阶函数 func(name,age) } higherOrderFun1(saySome1,"zm",39) // 调用高阶函数 // 高阶函数功能2 将函数作为返回值 // 匿名函数作为返回值赋值给另一个函数 def highOrderFun2(msg:String) = (name:String) => {println(msg + " : "+ name)} // var doSome = highOrderFun2("highOrderFun2") // doSome = { (name:String) => {println(highOrderFun2 + ":" + name)} } doSome("zm") // doSome("zm") = { (name:String) => {println(highOrderFun2 + ":" + zm)} } ----》 结果就是 highOrderFun2 : zm doSome("liang") /** * 高阶函数的类型推断 * 1 可以自动推断参数类型,可以不写参数类型 * 2 对于只有一个参数的 可以省略参数的小括号 * 3 如果只有一个参数且函数体内只使用一次则在函数体内 形参可用 _ 替代 * 4 在spark源码中经常使用到 */ def greeting(func:(String)=>Unit,name:String) {func(name)} // 定义高级函数 greeting((name:String)=>{println("hello " + name)},"leo") // 调用 greeting(name=>println("hello1 " + name),"leo")// 参数类型可以不写 形参小括号可以不带 def triple(func:(Int) => Int ) {func(3)} // 形参是一个 可以将形参名也去掉 println(triple(4 * _)) // 4 * _ 作为一个操作当成一个整个给了形参 func:(Int) => Int , 函数体是 {func(3)} 其中 在定义函数func时 因为只有一个参数且在函数体只用了一次因此这个形参用_表示 // 而函数体 {func(3)}中 给这个唯一使用的形参赋值为3 因此针对操作 4 * _ ,在函数体{func(3)} 针对形参进行了赋值 就变成了 4 * 3 = 12 /** * 在执行 triple(4 * _) 时, 4*_ 这个操作 等同于 func:(Int) => Int triple函数的函数体是 func(3) 其中操作 4*_中的_表示函数func中的参数因为只有一个切在函数体内只用到一次因此用_ * 而函数体 func(3)就是给这个形参赋值 因此操作 4*_ 就是 4*3 = 12 */ /** * scala中的高级函数 * */ var newArray = Array(1,2,3,4).map((num:Int) => {num * num}) // 数组array中使用匿名函数案例 println(newArray.mkString(",")) // 1,4,9,16 // 数组使用map方法对每个元素映射 Array(1,2,3,4,5).map(2*_) Array(1,2,3,4).map((num:Int)=>{num * num}) var newArray1 = Array(1,2,3,5,6,7).map(2*_) println(newArray1.mkString(",")) // 序列使用 map方法 var c = (1 to 5).map(2*_) println( c.mkString("-")) // foreach方法 (1 to 5).map(3+_).foreach(println _ ) Array(1,2,3,4,5).map(2 + _).foreach(println _ ) // filter方法 (1 to 5).filter(_%2 == 0).foreach(println(_)) Array(1,2,3,4,5).filter(_%2!=0).foreach(println(_)) // reduceLeft 从左侧元素开始,进行reduce操作,即先对元素1和元素2进行处理,然后将结果与元素3处理,再将结果与元素4处理,依次类推 var resu = (1 to 3).reduceLeft(_ + _) println(resu) println(Array(1,2,3,4).reduceLeft(_+_)) // sortWith 对元素进行两两相比,进行排序 var newArr = Array(11,2,13,4).sortWith(_<_) println(newArr.mkString("-")) // 2-4-11-13 /** * 闭包 * 函数在变量不处于其有效作用范围时,还能够对变量进行访问 * 其中 msg参数定义在 匿名函数 (name:String) =>{println(msg + " , " + name)} 之外 * 但是匿名函数又能够访问到msg的值 这就是闭包 * 能够访问到的原理: Scala为每个函数创建对象来实现闭包 我理解就是 saySomething("nihao ") 创建对象1, 对象1里的参数msg = nihao 同理对象2里的msg = hello 这样这两个函数|对象就有了不同的msg值 * Scala编译器会确保上述闭包机制 */ def saySomething(msg : String) = (name:String) =>{println(msg + " , " + name)} var some1 = saySomething("nihao ") var some2 = saySomething("hello ") println(some1("zm")) // nihao , zm println(some2("zm")) // hello , zm /** * SAM转换 */ /** * Currying函数 * 将原来接收两个参数的函数,转换为两个函数 * 现象: 两个函数连续调用 */ def sum(a:Int,b:Int) = a + b println(sum(1,20)) def sum2(a:Int) = (b:Int) => a+b println(sum2(1)(20)) def sum3(a:Int)(b:Int) = a + b println(sum3(1)(20)) } def sayHello(name:String) {println("hello " + name)} }
posted on 2019-06-06 17:40 ligongda2006 阅读(157) 评论(0) 编辑 收藏 举报