1.函数式编程初步理解:啥是scala函数式编程
1.1函数在scala可以做任何事情
函数可以作为另一个函数的参数
函数可以作为另一个函数的返回值
函数可以赋值给一个变量
1.2.scala函数 VS java方法 :
1.java 方法 面向对象:多个方法之间可以有 对象关系:继承,实现,重写,多态。
解决问题时,将问题拆成一个个小问题(形成对象),分别解决
2.scala函数式编程:注重函数(功能),函数的入参 和 出参 ,注重问题的解决方案
2.函数定义,函数简化
2.1函数定义
def test0(i:Int):Int={
return i+3
}
2.2函数至简原则
Scala的编译器为了提高开发效率。帮助我们将函数声明中能简化的地方全部都进行了简化。也就是说将函数声明中那些能省的地方全部都省掉。所以简单来说就是:能省则省
/**
* 简化
* 1.不加return 关键字会返回最后一行代码
* 2.返回值类型也可省略 自动推断
*/
def test() ={
"zhangsan"
}
//2.如果函数体中只有一行代码 大括号也可省略
def test1() = "zhangsan"
//3.如果函数中没有入口参数 那么小括号也可以省略
def test2 = "zhangsan"
//小括号省略后 调用函数时 也不能加小括号
print(test)
3. scala 函数参数
// TODO scala 函数可变参数,可以传0个或多个参数
// 类似于java中的方法重载,在java中要定义多个同名方法,参数不同
def test(name: String*): Unit ={
printf(s"${name}")
}
test("zhangsan","lisi","wangwu") //输出:WrappedArray(zhangsan, lisi, wangwu)
// TODO scala 函数设置参数默认值
def test2(name:String,age:Int=20): Unit ={
printf(s"${name} - ${age}")
}
test2("zhangsan") //输出:zhangsan - 20
//如果 带默认值的参数顺序在前
def test3(name1:String="007",name2:String): Unit ={
printf(s"${name1} - ${name2}")
}
test3("zhangsan") //会报错
// 因为参数从左到右匹配 第一个参数赋值给了name1 那么默认值不起作用了
//由此引入 scala带名参数 这样就不怕参数顺序问题 使得默认值不起作用了
//正解如下: 带名参数
test3(name2="zhangsan") //输出结果:007 - zhangsan
4.函数在scala可以做任何事情,示例:
1.函数可以赋值给一个变量 上节提到 因为调用时 无参函数的() 可以省略 即 可写成 f1 所以要返回函数本身 而不是返回函数的调用值 需要加_ 下划线分开 即 写为 f1 _
val a = f1 _
概念定义:匿名函数 可简化为匿名函数 箭头左边是参数列表,右边是函数体 例如(x:Int)=> x+1 括号中x为函数参数 x+1为函数返回值
val b = (x:Int)=> x+1
2.一个函数作为另一个函数的参数 例: a.定义一个参数为函数 的函数 f2 b.调用方法: f2(f1)
def f2(f: Int=> Int) ={
f()
}
println(f2(f1)) //输出为HELLO
3.一个函数作为另一个函数的返回值 例: a.定义一个返回值为函数的 函数 f3 b.调用方法 :f3()() 第一个括号时调用f3 第二个括号是调用f1
def fa () ={
"hello"
}
def f3() ={
fa _
}
println(f3()()) //输出为hello
3.1 简化 由于定义时 需要声明两个函数 f3 fa 不太简便 可读性有待提高 所以演化出以下写法 直接写在一起
//无参情况 示例:
def f4() ={
def f5:String ={
"World"
}
f5 _
}
println(f4()())
//有参情况 示例:
def f6(i:Int) ={
def f7(j:Int) ={
i*j //此处变量i 不属于函数f7作用域 但在此处却能取到值 这里涉及到闭包的概念
}
f7 _
}
println(f6(3)(7))
* 概念定义: 闭包 * 这样定义的函数变量 f7 成为一个“闭包”, * 因为它引用到函数外面定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。 * 有意思的是,当这个自由变量发生变化时,Scala 的闭包能够捕获到这个变化,因此 Scala 的闭包捕获的是变量本身而不是当时变量的值。
3.2 f6 f7 简化 将f7变成匿名函数(j:Int) => i*j 得到下列
def f8(i:Int) = (j:Int) => i*j
3.3 f8 再次简化 * 此简化方法由 curry 提出 所以命名为 柯里化(Currying)
def f9(i:Int)(j:Int) ={
i*j
}
* 概念定义: 柯里化(Currying) * 原来接受 `多个参数` 变成 接收`一个参数` 的函数(第二个参数 为 另一个函数的参数)