package chapter05 object Test01_FunctionAndMethod { def main(args: Array[String]): Unit = { //定义函数 def sayHi(name:String):Unit={ println("hi,"+name) } //调用函数 sayHi("alice") //调用对象方法 Test01_FunctionAndMethod.sayHi("bob") //获取对象返回值 val result = Test01_FunctionAndMethod.sayHello("cary") println(result) } //定义对象的方法 def sayHi(name:String):Unit={ println("Hi,"+name) } def sayHello(name:String):String={ println("Hello,"+name) return "hello" } }
package chapter05 object Test02_FunctionDefine { def main(args: Array[String]): Unit = { // (1) 函数 1:无参,无返回值 def f1():Unit={ println("1:无参,无返回值") } f1() println(f1()) println("-------------------------------------------") // (2) 函数 2:无参,有返回值 def f2():Int={ println("2:无参,有返回值") return 12 } println(f2()) println("--------------------------------------") // (3) 函数 3:有参,无返回值 def f3(name:String):Unit={ println("3:有参,无返回值"+name) } println(f3("alice")) println("--------------------------------------------") // (4) 函数 4:有参,有返回值 def f4(name:String):String={ println("4:有参,有返回值"+name) return "hi,"+name } println(f4("alice")) println("---------------------------------") // (5) 函数 5:多参,无返回值 def f5(name1:String,name2:String):Unit={ println("5:多参,无返回值") println(s"${name1}和${name2}都是我的好朋友") } f5("alice","bob") println("------------------------------------------") // (6) 函数 6:多参,有返回值 def f6(a:Int,b:Int):Int={ println("6:多参,有返回值") return a+b } println(f6(12,37)) } }
package chapter05 object Test03_FunctionParameter { def main(args: Array[String]): Unit = { // (1) 可变参数 WrappedArray包装起来的数组 Scala抽象的集合类型 def f1(str:String*):Unit={ println(str) } f1("alice") f1("aaa","bbb","ccc") println("-------------------------------------") // (2) 如果参数列表中存在多个参数,那么可变参数一般放置在最后 *归属于最后 def f2(str1:String,str2:String*):Unit={ println("str1:"+str1+"t str2:"+str2) } f2("alice") f2("aaa","bbb","ccc") println("------------------------------------------") // (3) 参数默认值,一般将有默认值的参数放置在参数列表的后面 def f3(name:String="bigdata"):Unit={ println("my school is "+name) } f3("school") f3() println("------------------------------------------") // (4) 带名参数 有默认值时比较常用 def f4(name:String="bd",age:Int):Unit={ println(s"${age}岁的${name}在学习大数据") } f4("zhangsan",22) f4(age=23,name="lisi") f4(age=25) } }
package chapter05 //函数至简原则 object Test04_Simplify { def main(args: Array[String]): Unit = { def f0(name:String):String={ return name } println("bd") println("--------------------------------------") // (1) return 可以省略,Scala 会使用函数体的最后一行代码作为返回值 def f1(name:String):String={ name } println(f1("zs")) println("-------------------------------------------------") // (2) 如果函数体只有一行代码,可以省略花括号 def f2(name:String):String =name println("zs") println("---------------------------------------") // (3) 返回值类型如果能够推断出来,那么可以省略(:和返回值类型一起省略) //函数式编程 关注的就是数学上的映射关系 def f3(name:String)=name println("zs") println("-----------------------------------") // (4) 如果有 return,则不能省略返回值类型,必须指定 //要省略 一起省略 def f4(name:String)={ name } println("bd") println("--------------------------------------") // (5) 如果函数明确声明 unit,那么即使函数体中使用 return 关键字也不起作用 def f5(name:String):Unit={ return name } println("bd") println("--------------------------------") // (6) Scala 如果期望是无返回值类型,可以省略等号 def f6(name:String){ println(name) } // (7) 如果函数无参,但是声明了参数列表,那么调用时,小括号,可加可不加 def f7():Unit={ println("kkxx") } f7() f7 println("------------------------------") // (8) 如果函数没有参数列表,那么小括号可以省略,调用时小括号必须省略 def f8:Unit={ println("kkll") } f8 println("-------------------------------") // (9) 如果不关心名称,只关心逻辑处理,那么函数名(def)可以省略 def f9(name:String):Unit={ println(name) } //匿名函数 lambda表达式 (name:String)=>{println(name)} } }
package chapter05 object Test05_Lambda { def main(args: Array[String]): Unit = { val fun=(name:String)=> {println(name)} fun("zhangsan") println("---------------------------") //定义一个函数,以函数作为参数输入 def f(func:String=>Unit):Unit={ func("lisi") } f(fun) f((name:String)=> {println(name)}) println("---------------------------------") //匿名函数的简化原则 // (1) 参数的类型可以省略,会根据形参进行自动的推导 f((name)=>{ println(name) }) // (2) 类型省略之后,发现只有一个参数,则圆括号可以省略;其他情况:没有参数和参 // 数超过 1 的永远不能省略圆括号。 f(name =>{ println(name) }) // (3) 匿名函数如果只有一行,则大括号也可以省略 f(name =>println(name)) // (4) 如果参数只出现一次,则参数省略且后面参数可以用_代替 f(println(_)) // (5) 如果可以推断出 当前传入的println是一个函数体 而不是调用语句 可以直接省略下划线 f(println) println("-----------------------------------------") //实际示例,定义一个"二元运算“函数,只 *** 作1和2两个数,但是具体运算通过参数传入 def dualFunctionOneAndTwo(fun:(Int,Int)=>Int):Int={ fun(1,2) //这里1,2直接写死 只能调用1,2 } val add=(a:Int,b:Int)=>a+b val minus=(a:Int,b:Int)=>a-b println(dualFunctionOneAndTwo(add)) println(dualFunctionOneAndTwo(minus)) println("---------------------------------") //匿名函数简化 println(dualFunctionOneAndTwo((a:Int,b:Int)=>a+b)) //fun Int Int已经写死了 不用再定义Int println(dualFunctionOneAndTwo((a:Int,b:Int)=>a-b)) println("---------------------------------") println(dualFunctionOneAndTwo((a,b)=>a+b)) println(dualFunctionOneAndTwo(_+_)) println(dualFunctionOneAndTwo(_-_)) println("--------------------------------------") println(dualFunctionOneAndTwo((a,b)=>b-a)) //-a+b println(dualFunctionOneAndTwo(-_+_)) } }
package chapter05 object Test06_HighOrderFunction { def main(args: Array[String]): Unit = { def f(n:Int):Int={ //最简单的函数声明和调用 println("f调用") n+1 } def fun():Int={ println("fun调用") 1 } val result:Int=f(123) println(result) fun() fun println("---------------------------------------") //1.函数可以作为值进行传递 val f1:Int=>Int=f val f2 =f _ println(f1) println(f1(12)) println("--------------------------------------") println(f2) println(f2(35)) println("----------------------------------------") // val f3=fun //引用 //此时f3 f4 都为函数 val f3:()=>Int=fun val f4=fun _ println(f3) println(f4) println("---------------------------------------") //2.函数作为参数进行传递 //定义二元计算函数 //两个int类型的参数 得到一个int类型的返回值 传入的数据是什么 def dualeval(op:(Int,Int)=>Int,a:Int,b:Int):Int={ op(a,b) } def add(a:Int,b:Int):Int={ a+b } println(dualeval(add,12,35)) println(dualeval((a,b)=>a+b,12,35)) println(dualeval(_+_,12,35)) //3.函数作为函数的返回值返回 def f5(): Int=>Unit={ def f6(a:Int):Unit={ println("f6调用"+a) } f6 //将函数直接返回 } println(f5()) //返回的是函数f6 println("---------------------------") val f6=f5() println(f6) println(f6(25)) //()是f6本身没有返回值 Unit println("----------------------------") println(f5()(25)) } }
package chapter05 object Test07_Practice_CollectionOperation { def main(args: Array[String]): Unit = { val arr:Array[Int]=Array(12,45,75,98) //对数组进行处理,将 *** 作抽象出来,处理完毕之后的结果返回一个新的数组 def arrayOperation(array:Array[Int],op:Int=>Int):Array[Int]={ for(elem <- array) yield op(elem) } //对op进行操作 返回一个新的数组 //定义一个加一操作 def addOne(elem:Int):Int={ elem+1 } //调用函数 val newArray:Array[Int]=arrayOperation(arr,addOne) println(newArray.mkString(",")) //传入匿名函数,实现元素翻倍 val newArray2=arrayOperation(arr,_*2) //(arr,elem=>elem*2) println(newArray2.mkString(",")) } }
package chapter05 object Test08_Practice { def main(args: Array[String]): Unit = { //练习1 val fun =(i:Int,s:String,c:Char) => {if(i==0 && s=="" && c=='0') false else true} println(fun(0,"",'0')) println(fun(0,"",'1')) println(fun(23,"",'0')) println(fun(0,"hello",'0')) println("------------------------------------") //2.练习2 def func(i:Int):String=>(Char=>Boolean)={ //嵌套 内层函数保存下来 def f1(s:String):Char=>Boolean ={ def f2(c:Char):Boolean = { if(i==0 && s=="" && c=='0') false else true } f2 } f1 //整体返回 } println(func(0)("")('0')) println(func(0)("")('1')) println(func(23)("")('0')) println(func(0)("hello")('0')) println("-------------------------------------") //匿名函数简写 def func1(i:Int):String=>(Char=>Boolean)={ s => c =>if(i==0 && s=="" && c=='0') false else true } //内层函数可以直接使用外层函数的参数的 相当于外层定义好的参数和变量 可以传递到内层函数里面去做处理 println(func1(0)("")('0')) println(func1(0)("")('1')) println(func1(23)("")('0')) println(func1(0)("hello")('0')) //底层有相关的打包和优化时 可以放在一起 就是闭包 println("-------------------------------------") //柯里化 def func2(i:Int)(s:String)(c:Char):Boolean={ if(i==0 && s=="" && c=='0') false else true } println(func2(0)("")('0')) println(func2(0)("")('1')) println(func2(23)("")('0')) println(func2(0)("hello")('0')) } }
package chapter05 //闭包 柯里化 object Test09_ClosureAndCurrying { def main(args: Array[String]): Unit = { def add(a:Int,b:Int):Int={ a+b } //1.考虑固定一个加数的场景 def addByFour(b:Int):Int={ 4+b } //2.扩展固定加数改变的情况 def addByFive(b:Int):Int={ 5+b } //3.将固定加数作为另一个参数传入,但是是作为“第一层参数”传入 万能钥匙->百能钥匙 def addByFour1():Int=>Int={ //内层函数用到了外层函数的一个局部变量 val a=4 def addB(b:Int):Int={ a+b } addB } def addByA(a:Int):Int=>Int ={ def addB(b:Int):Int={ a+b } addB } println(addByA(35)(24)) println("----------------------------------") val addByFour2=addByA(4) val addByFive2=addByA(5) println(addByFour2(13)) println(addByFive2(25)) //4.lambda表达式简写 闭包 def addByA1(a:Int):Int=>Int={ (b:Int)=>{ a+b } } def addByA2(a:Int):Int=>Int={ b => a+b } def addByA3(a:Int):Int=>Int=a + _ val addByFour3=addByA3(4) val addByFive3=addByA3(5) println(addByFour3(13)) println(addByFive3(25)) println("-----------------------------") //5.柯里化 def addCurrying(a:Int)(b:Int):Int={ //分层调用 一旦用到柯里化 底层一定是闭包 a+b } println(addCurrying(35)(24)) } }
package chapter05 import scala.annotation.tailrec object Test10_Recursion { def main(args: Array[String]): Unit = { println(fact(5)) println(tailFact(5)) } //递归实现计算阶乘 纯函数编程语言可以只使用递归 但耗费栈资源 //一次次覆盖 不耗费栈资源 def fact(n:Int):Int={ if(n==0) return 1 fact(n-1)*n } //尾递归实现 java可以写成尾递归的形式 但是却是无效的 尾递归的优化是依赖编译器的 //需要编译器知道 在栈帧里面覆盖 而不是做压栈 //真正的函数式语言 都会支持尾递归的 def tailFact(n:Int):Int={ @tailrec def loop(n:Int,currRes: Int):Int={ if(n==0) return currRes loop(n-1,currRes*n) //把最后要做计算的*n放在了另一个参数 保存在当前乘积计算结果上面 //在栈帧里面覆盖 } loop(n,currRes = 1) } }
package chapter05 object Test11_ControlAbstraction { def main(args: Array[String]): Unit = { //1.传值参数 def f0(a:Int):Unit={ println("a:"+a) println("a:"+a) } f0(23) def f1():Int={ println("f1调用") 12 } f0(f1()) println("-----------------------------------") //2.传名参数 传递的不再是具体的值,而是一部分代码块 def f2(a: =>Int):Unit={ println("a:"+a) println("a:"+a) } f2(23) println("-------------------------------------") f2(f1()) //这里并不是调用几次 执行几次 是要看传名参数的代码块 //控制抽象 传名参数的代码块 赋给了a a执行几次 f1就会被调用几次 println("--------------------------------") f2({ println("这是一个代码块") 29 }) } }
package chapter05 object Test12_MyWhile { def main(args: Array[String]): Unit = { var n =10 //1.常规的while循环 while(n>=1) { println(n) n -= 1 } //2.用闭包实现一个函数,将代码块作为参数传入,递归调用 def myWhile(condition: =>Boolean):(=>Unit)=>Unit ={ //内层函数需要递归调用,参数就是循环体 def doLoop(op: =>Unit):Unit={ if(condition){ op myWhile(condition)(op) } } doLoop _ } n=10 myWhile((n>=1))({ println(n) n-=1 }) //3.用匿名函数实现 def myWhile2(condition: =>Boolean):(=>Unit)=>Unit ={ //内层函数需要递归调用,参数就是循环体 op =>{ if(condition){ op myWhile2(condition)(op) } } } println("-------------------------------") n=10 myWhile((n>=1)){ println(n) n-=1 } //4.用柯里化实现 def myWhile3(condition: =>Boolean)(op :Unit):Unit = { if (condition) { op myWhile2(condition)(op) } } println("-------------------------------") n=10 myWhile((n>=1)){ println(n) n-=1 } } }
package chapter05 //惰性求值 object Test13_Lazy { def main(args: Array[String]): Unit = { lazy val result:Int = sum(13,47) println("1,函数调用") println("2,result="+result) println("4,result="+result) //已经计算出来 不需要再次计算 } def sum(a: Int, b: Int):Int={ println("3,sum调用") a+b } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)