说明:本文将知识点全部写在代码中,后续再拿出来总结吧
一.函数式编程
Scala关心三个点:函数,函数入口参数,函数返回结果
主要关心解决方案
代码:
package com.zpark.bigdata.scala.chapter05
object Scala01_Function {
def main(args: Array[String]): Unit = {
//TODO 函数式编程
//编程的范式(规范形式)
//面向对象:解决问题时将问题分解成一个一个小问题(形成了对象),分别解决
// 对象关系:继承,实现,多态,重写 TODO 主要关心他们之间的关系
//函数式编程关心的是问题解决的方案(封装功能):重点在于函数(功能)函数入参,出参
// 关心三个点:函数,函数入口参数,函数返回结果 TODO 主要关心解决方案
//函数式编程重要的是函数
//TODO Java中的方法和Scala中的函数都可以进行功能的封装,但是方法必须和类型绑定,但是函数不需要
//声明函数
// Java方法声明
//public static void test (String s){ 方法体}
//Scala函数声明
//TODO Scala语法很灵活,在任意语法中可以声明其他语法规则
def test(s: String):Unit={
//函数体
println(s)
}
//调用函数
test("zhangsan")
}
}
二.函数:入参(方法参数),出参(返回值)
代码:
package com.zpark.bigdata.scala.chapter05
object Scala02_Function01 {
def main(args: Array[String]): Unit = {
//函数:入参(方法参数),出参(返回值)
//无参,无返回值
def test():Unit={
println("Test")
}
test()
//有参,无返回值
//TODO 函数没有重载的概念
//TODO 如果在同一作用域中,函数不能重名
def test1(s:String):Unit = {
println(s)
}
test1("zhangsan")
//有参,有返回值
def test2(s:String):String = {
return s + "........"
}
val rtnVal: String = test2("lisi")
println(rtnVal)
//无参,有返回值
def test3(): String ={
return "Hello World"
}
println(test3())
//Scala中没有throws关键字,所以函数中如果有异常发生,也不需要在函数声明时抛出异常
}
}
三.函数简化过程
package com.zpark.bigdata.scala.chapter05
object Scala03_Function02 {
def main(args: Array[String]): Unit = {
//TODO Scala中可以采用自动推断功能来简化函数的声明
//1.如果函数声明中,明确无返回值Unit,那么即使函数中有return也不起作用
/*
def test(): Unit ={
//println("Hello World")
return "zhangsan"
}
*/
//2.如果将函数体最后一行代码进行返回,那么return关键字可以省略
/*
def test(): String ={
//return"zhangsan"
"zhangsan"
}
*/
//3.如果可以根据函数的最后一行代码推断类型,那么函数返回值类型可以省略
/*
def test()={
"zhangsan"
}
*/
//4.如果函数体重只有一行代码,大括号可以省略
//def test()="zhangsan"
//5.TODO 如果函数声明中没有参数列表,小括号可以省略
//TODO 如果函数小括号省略,那么访问时不能加小括号
//TODO 声明函数必须加def def:声明函数 val:变量
def test="zhangsan"
// val test1="lisi"
println(test)
//如果明确函数没有返回值,那么等号可以省略,省略后,编译器不会将函数体最后一行代码作为返回值
//如果函数没有参数列表,可以省略小括号,调用时一定不能使用小括号
//如果函数没有参数列表,但是没有省略小括号,调用时可加可不加
//扩展:匿名函数
()->{println("vvvvvvvvvvv")}
}
}
四.函数式编程:扩展
1.可变参数
2.默认参数
3.带名参数
package com.zpark.bigdata.scala.chapter05
object Scala04_FunctionHard {
def main(args: Array[String]): Unit = {
//函数式编程:扩展
//TODO 可变参数
def test(name:String*): Unit ={
println(name)
}
//调用函数时,可传多个参数,也可以不传参数
//test("zhangsan","lisi","wangwu")
//运行后结果 WrappedArray(zhangsan, lisi, wangwu)
//test()
//运行后结果List()
//TODO 默认参数
//如果希望函数中的某一个参数使用默认值,那么可以在声明时直接赋初始值
//Int = 20 就是默认值
def test1(name: String,age:Int = 20): Unit ={
println(s"${name} - ${age}")
}
def test2(name2:String = "lisi",name1:String): Unit ={
println(s"${name1} - ${name2}")
}
test1("zhangsan",22)
//调用函数时,参数匹配规则为从前到后,从左到右
//test2("zhangsan","wangwu")
//TODO 带名参数
//能明确传那个值
test2(name1="zhangsan")
}
}
五.函数式编程--地狱(重点)
代码主要内容:
1.Scala是完全面向函数式编程语言
函数可以在Scala中做任何事情
函数可以赋值给变量
函数可以作为函数的参数
函数可以作为函数的返回值
2.函数柯里化
3.闭包
一个函数在实现逻辑时,将外部的变量引入到函数的内容,改变了这个变量的声明周期,称之为闭包
4.使用匿名函数改善代码
实现把一段逻辑传递给另外一个函数
代码练习及说明如下
package com.zpark.bigdata.scala.chapter05
object Scala05_FunctionHell {
def main(args: Array[String]): Unit = {
//函数式编程 - 地狱
//TODO Scala是完全面向函数式编程语言
//函数可以在Scala中做任何事情
//函数可以赋值给变量
//函数可以作为函数的参数
//函数可以作为函数的返回值
//例一
/*
def f(): Unit ={
println("function")
}
def f0() = {
//返回值
//直接返回函数,有问题,需要增加特殊符号:下划线
f _
}
f0()()
*/
//解释f0()()
// val ff: () => Unit = f0()
// ff()
//例二:嵌套写法
/*
def f1(i:Int) ={
def f2(j:Int): Int ={
i * j
}
f2 _
}
println(f1(10)(2))
*/
//TODO 函数柯里化
/*
def f3(i:Int)(j:Int):Int = {
i * j
}
println(f3(2)(5))
*/
//TODO 闭包
//一个函数在实现逻辑时,将外部的变量引入到函数的内容,改变了这个变量的声明周期,称之为闭包
/*
def f1(i:Int) ={
def f2(j:Int): Int ={
i * j
}
f2 _
}
f1(10)(2)
*/
//将函数作为参数传递给另一个函数,需要采用特殊的声明方式
//()=>Unit
//参数列表=>返回值类型
/*
def f4(f :()=>Int): Int ={
f() + 10
}
def f5(): Int ={
6
}
println(f4(f5))
*/
//TODO 使用匿名函数改善代码
//把一段逻辑传递给另外一个函数
/*
def f6(f:()=>Unit): Unit ={
f()
}
f6(()=>(println("xxxxxxxxx")))
*/
//例1
/*
def f7(f:(Int)=>Unit): Unit ={
f(10)
}
def f8(i:Int): Unit ={
println(i)
}
f7(f8)
*/
//匿名函数写法
/*
def f7(f:(Int)=>Unit): Unit ={
f(10)
}
//TODO 简化过程
//f7((i:Int)=>{println(i)})
//1.前面声明时已经明确了要给一个Int类型的值,所以Int可以省略
//f7((i)=>{println(i)})
//2.如果花括号里只有一行代码的话,花括号可以被省略
//f7((i)=>println(i))
//3.当参数只用到了一次,参数可以用特殊符号下划线来代替参数
//f7(println(_))
//4.既然只有一个参数,那么下划线也可以被省略
f7(println)
*/
//例2
def f9(f:(Int,Int)=>Int): Int ={
f(10,10)
}
// def f10(i:Int,j:Int): Int ={
// i + j
// }
// println(f9(f10))
//用匿名函数的方式来声明
//TODO 简化过程
//println(f9( (x:Int,y:Int)=>{x+y}))
//1.前面声明时已经明确了要给一个Int类型的值,所以Int可以省略
//println(f9( (x,y)=>{x+y}))
//2.如果花括号里只有一行代码的话,花括号可以被省略
//println(f9( (x,y)=>x+y))
//3.当参数只用到了一次,参数可以用特殊符号下划线来代替参数
println(f9(_+_))
}
}
六.递归函数
package com.zpark.bigdata.scala.chapter05
object Scala06_RecursionFunction {
def main(args: Array[String]): Unit = {
//TODO 递归
//1.函数的逻辑代码中调用自身
//2.函数在调用自身时,传递的参数应该有规律
//3.函数应该有跳出递归的逻辑,否则出现死循环
//4.递归函数无法推断出函数的返回值类型。所以必须要声明
//TODO 阶乘 = 一个大于1的数的阶乘 = 这个数 * (数 - 1)阶乘
//例:5的阶乘= 5*4*3*2*1 = 120
def !!(i:Int): Int ={
if (i == 1){
1
}else{
i * !!(i-1)
}
}
//5的阶乘= 5*4*3*2*1 = 120
println(!!(5))
}
}
七.简化还原
package com.zpark.bigdata.scala.chapter05
object Scala07_RevFunction {
def main(args: Array[String]): Unit = {
//TODO 反转简化后的函数
//f1是简化后的写法,f2是正常写法
/*
def f1 = "zpark"
def f2(): String ={
"zpark"
}
println(f1)
*/
//function类型最大为22
val f = () => {}
//当前输出为<function0> 个数就算是()里参数的个数,最大为22
println(f)
}
}
八. 惰性函数
package com.zpark.bigdata.scala.chapter05
object Scala08_LazyFunction {
def main(args: Array[String]): Unit = {
//TODO 惰性函数
/*
1.lazy 不能修饰 var 类型的变量
2.不但是 在调用函数时,加了 lazy ,会导致函数的执行被推迟,
我们在声明一个变量时,如果给声明了 lazy ,那么变量值得分配也会推迟。
比如 lazy val i = 10
*/
lazy val res = sum(10, 20)
println("-----------------")
println("res=" + res)
}
def sum(n1 : Int, n2 : Int): Int = {
println("sum() 执行了..")
return n1 + n2
}
}
九.异常处理
package com.zpark.bigdata.scala.chapter05
object Scala09_Exception {
def main(args: Array[String]): Unit = {
//异常
try{
val i = 10
val j = 0
val k = i/j
}catch {
//类似于java中switch用法
//语法规则类似于匿名函数
case ex:ArithmeticException =>println("捕捉了算术为0的算术异常")
case ex:Exception =>println("捕捉了异常")
}finally {
println("finally......")
}
}
}
附加.工程图示