文章目录
一 函数式编程
函数:function,功能的封装,不强调功能的从属关系,是功能的编程
方法:也是功能的封装,但强调的是功能属于谁
面向对象编程,解决问题都是按照面向对象的方式来处理的。比如用户登陆等业务功能。
函数式编程,采用函数式编程的思路来解决问题。scala编程语言将函数式编程和面向对象编程完美地融合在一起了。
- 面向对象编程:分解对象,行为,属性,然后通过对象的关系以及行为的调用来解决问题
- 函数式编程:将问题分解成一个一个的步骤,将每个步骤进行封装(函数),通过调用这些封装好的功能按照指定的步骤,解决问题。
1 基础函数编程
1.1 基本语法
[修饰符] def 函数名 ( 参数列表 ) [:返回值类型] = {
函数体
}
private def test( s : String ) : Unit = {
println(s)
}
1.2 函数和方法
scala 中存在方法与函数两个不同的概念,二者在语义上的区别很小。scala 方法是类的一部分,而函数是一个对象,可以赋值给一个变量。换句话来说在类中定义的函数即是方法。scala 中的方法跟 Java 的类似,方法是组成类的一部分。scala 中的函数则是一个完整的对象。
Scala中的方法和函数从语法概念上来讲,一般不好区分,所以简单的理解就是:方法也是函数。只不过类中声明的函数称之为方法,其他场合声明的就是函数了。类中的方法是有重载和重写的。而函数没有重载和重写的概念,但是函数可以嵌套声明使用,方法就没有这个能力了。
函数作用域比较窄,方法的作用域比较大。
函数的本质:编译后,函数会被编译为一个新的方法 private static final unit 方法名,当函数名和方法名同时存在时默认会调用函数。
def main(args: Array[String]): Unit = {
//TODO 函数式编程
def test(): Unit ={
println("test function")
def test2(): Unit ={
}
}
test()
this.test()
}
def test(): Unit ={
println("test method")
}
def test(name:String): Unit ={
println("test method")
}
1.3 函数定义
1.3.1 无参,无返回值
如果函数声明时,没有参数,则调用时,可以省略小括号。
def main(args: Array[String]): Unit = {
def fun1(): Unit = {
println("函数体")
}
fun1()
}
1.3.2 无参,有返回值
def main(args: Array[String]): Unit = {
def fun2(): String = {
return "zhangsan"
}
println( fun2() )
}
1.3.3 有参,无返回值
参数的声明方式:参数名:参数类型。
当参数有参数时,调用时应该传递相同类型的参数。
函数的参数只有一个也不能省略小括号,方法可以,但函数不行,因为方法隶属于对象。
def main(args: Array[String]): Unit = {
def fun3( name:String ): Unit = {
println( name )
}
fun3("zhangsan")
}
1.3.4 有参,有返回值
def main(args: Array[String]): Unit = {
def fun4(name:String): String = {
return "Hello " + name
}
println( fun4("zhangsan") )
}
1.3.5 多参,无返回值
函数存在多个参数,调用时应该匹配个数、类型和顺序,按照顺序进行匹配。
java中方法参数的传递都是值传递,引用类型变量的值就是它的内存地址(User)。
def main(args: Array[String]): Unit = {
def fun5(hello:String, name:String): Unit = {
println( hello + " " + name )
}
fun5("Hello", "zhangsan")
}
1.3.6 多参,有返回值
def main(args: Array[String]): Unit = {
def fun6(hello:String, name:String): String = {
return hello + " " + name
}
println( fun6("Hello", "zhangsan"))
}
1.4 函数参数
1.4.1 多参
参数个数:函数的参数个数没有限制。
1.4.2 可变参数
参数的个数在某些情况下,不能固定,使用可变参数,得到的都是集合对象,如果一个参数都没有,返回空集合list()。
def main(args: Array[String]): Unit = {
def fun7(names:String*): Unit = {
println(names)
}
fun7()
fun7( "zhangsan" )
fun7( "zhangsan", "lisi" )
}
可变参数不能放置在参数列表的前面,一般放置在参数列表的最后,即使参数的类型不同,可变参数放在开头,也不能分别识别。
def main(args: Array[String]): Unit = {
// Error
//def fun77(names:String*, name:String): Unit = {
//}
def fun777( name:String, names:String* ): Unit = {
println( name )
println( names )
}
}
1.4.3 参数默认值
声明参数的同时设定默认值,底层编译为一个方法,当不传参数时,由编译器自动调用这个方法
使得函数某个参数的值如果不传就固定下来。
调用时,如果想使用默认值,可以不传参数,如果不像使用默认值,直接传递参数即可。
函数的参数默认以val声明,意味着不能修改。
可逆加密:双方都可以通过某一规则接触密文。
不可逆加密:信息的内容只有发送信息的一方直到。
def main(args: Array[String]): Unit = {
def fun8( name:String, password:String = "000000" ): Unit = {
println( name + "," + password )
}
fun8("zhangsan", "123123")
fun8("zhangsan")
}
1.4.4 带名参数
传递参数时,增加参数的的名称,用于改变传参的顺序。
参数在传递时默认为顺序匹配,scala可以通过特殊的语法改变传值的顺序。
def main(args: Array[String]): Unit = {
def fun9( password:String = "000000", name:String ): Unit = {
println( name + "," + password )
}
fun9("123123", "zhangsan" )
fun9(name="zhangsan")
}
底层实现:将参数在外面声明,根据传值的方式去分别设定。
String x$1 = "zhangsan"; String x$2 = fun9$default$1$1(); fun9$1(x$2, x$1);
1.4.5 函数至简原则
逻辑简单,开发方便
写程序时,如果编译器能识别的语法和逻辑,程序员可以不去写
(1)省略return关键字
在函数定义时,已经明确告诉编译器有返回值了,那么就一定会有返回值,所以return关键字可以省略。
函数体会将满足条件的最后一行代码的执行结果作为函数的返回值。
def main(args: Array[String]): Unit = {
def fun1(): String = {
return "zhangsan"
}
def fun11(): String = {
"zhangsan"
}
}
(2)省略花括号
如果函数体的逻辑代码只有一行,那么花括号可以省略
def main(args: Array[String]): Unit = {
def fun2(): String = "zhangsan"
}
(3)省略返回值类型
如果函数返回数据,能够在数据中推荐出返回值类型的话,那么返回值类型可以省略
def main(args: Array[String]): Unit = {
def fun3() = "zhangsan"
}
(4)省略参数列表
如果函数的参数列表中没有声明任何的参数(无参),那么参数列表可以省略
当函数省略参数列表的声明时,调用这个函数不能增加小括号
def main(args: Array[String]): Unit = {
def fun4 = "zhangsan"
fun4// √
fun4()//(ERROR)
}
java中没有def,val,var等关键字,scala有的原因就在这里。
(5)省略等号
省略等号后的函数称为过程函数
如果函数声明为Unit,那么函数体中的return不会被返回,return在此处的方法改为结束分支
def main(args: Array[String]): Unit = {
def fun5(): Unit = {
return "zhangsan"
}
println(fun5())
}
如果函数体中使用使用return返回结果,那么一定要声明返回值类型
def main(args: Array[String]): Unit = {
def fun55(): String = {
return "zhangsan"
}
println(fun5())
}
如果希望省略Unit,但同时又不希望函数体中的return起作用,那么可以将等号一起省略
def main(args: Array[String]): Unit = {
def fun555() {
return "zhangsan"
}
println(fun5())
}
(6)省略名称和关键字
称为匿名函数,无法调用,所以匿名函数不能独立使用
在某些场景下,数据的聚合更重要,而函数叫什么名字并不重要,可以省略名称和关键字
省略的同时也需要将返回值类型同时省略,并将等号增加一个箭头
def main(args: Array[String]): Unit = {
() => {
println("zhangsan")
}
}
当把函数给一个变量时,函数可以执行
def main(args: Array[String]): Unit = {
val f = () => {
"zhangsan"
}
println(f)
}
函数至简原则,能省则省,但有些地方不能省!