李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
大数据
正文
Scala总结(二)--函数
Leefs
2021-03-10 PM
1193℃
0条
# 14.Scala总结(二)--函数 ### 一、函数的声明和调用 **1.1 函数的声明** 格式 > 权限修饰符 函数名 (参数列表) : 返回值类型 = { 函数体 } 案例: ```scala def func(i:Int) : Unit = { println(i) } ``` **1.2 函数的调用** > 函数名(形参类表) ### 二、函数的定义 一共有如下6种情况: > 无参 *--> 无返回值、有返回值* > > 有参 *--> 无返回值、有返回值* > > 多参 *--> 无返回值、有返回值* 案例: ```scala object Scala_Method { def main(args: Array[String]): Unit = { //无参 -- 无返回值 def func1 () :Unit = { println("scala") } // func1() //无参 -- 有返回值 def func2 () :String = { "lilinchao博客" } val str = func2() // println(str) //有参 -- 无返回值 def func3 (i : Int ) : Unit = { println(i) } // func3(20) //有参 -- 有返回值 def func4 (i : Int) : String = { "我今年是" + i + "岁" } val str1 = func4(18) // println(str1) //多参 -- 无返回值 def func5(name:String,age:Int) : Unit = { println(s"name=${name},age =$age") } // func5("lilinchao博客",18) //多参 -- 有返回值 def func6(x:Int,y:Int):Int = { x-y } val i = func6(30,26) println(i) //4 } } ``` **2.1 可变参数** **定义:**Scala 允许你指明函数的最后一个参数可以是重复的,即我们不需要指定函数参数的个数,可以向函数传入可变长度参数列表。 **性质** > + 相同类型的参数出现多个,但是不确定个数时,使用可变参数 > + 表示方式 (i : Int * ) -->变量类型* > + 可变参数放置在形参类表的最后位置 *-->所以一个形参类列中只能有一个可变形参* > + 可变形参变量是一个集合,可以通过遍历的方式获取传入的每一个值 代码示例 ```scala def func1(i : Int* ) : Unit = { for (m <- i ) { println(m) } } func1(1,2,3,74) //运行结果:1 2 3 74 def func1(i: Int*): Unit = { println(i) } func1() //List() func1(1) //WrappedArray(1) func1(1, 2, 3, 74) //WrappedArray(1, 2, 3, 74) ``` **2.2 参数列表的默认值** **性质** > + scala中函数的参数是使用val进行声明的,所以不可变; > + scala中函数提供了参数默认值的语法来解决这个不可变的问题; > + 有默认值的参数,可以在调用函数时不传参数,则此时函数使用的是参数的默认值; > + 如果调用函数时,给有默认值的参数进行传参数了,那么会将参数的默认值进行覆盖; + 问题1:如何给参数进行设定默认值呢? ```scala //在形参列表中给参数进行初始化 def func3(i : Int = 1) : Unit = { println(i) } ``` - 问题2:如果形参类表中有些有参数,有些没有参数,而且在形参列表中的顺序不是连续,传参数时,如何进行区分是传递给哪个形参呢? > 原则一:函数在传递参数时,是从左到右依次进行匹配; > > 原则二:使用带名参数,指明给哪个参数进行传递参数。 **2.3 带名参数** 调用函数时使用注意事项: > 1.如果想跳过默认值对参数传参,则需要带名 > 2.因为传参数是按照从左到右的顺序,所以如果前面的形参已经传参数了,那么就可以不需要带名 示例 ```scala def fun4(i :Int , name :String ="lianzhipeng",age : Int, nation : String = "China") : Unit = { } fun4(20,age=20) ``` ### 三、函数的至简原则 scala中函数的至简原则:能省则省 ```scala def func1 () : String = { return "China" } ``` 首先将如上函数进行划分如下7个模块 > 1. def :函数或方法声明的关键字 > 2. func1 : 函数名 > 3. () : 形参列表 > 4. String :返回值类型 > 5. = :赋值操作符号 > 6. {} : 花括号,包裹函数体 > 7. return "China" : 函数体 *接下就是对这7个部分的省略的原则* **3.1 return省略** ``` 7. return "China" : 函数体 ``` 省略原则:当函数需要返回值时,都是将函数体中最后执行的代码作为返回结果,所以可以省略 return 关键字 省略return后代码: ```scala def func1 () : String = { "China" } ``` **3.2 返回值类型省略** ``` 4. String : 返回值类型 ``` *省略原则:如果编译可以推断出函数类型的返回值类型,则返回值类型可以省略* 省略后代码 ```scala def func1 () = { "China" } ``` **3.3 {}省略** ``` 6. {} : 花括号,包裹函数体 ``` *省略原则:如果函数体只有一段逻辑代码,那么大括号是可以省略* 理解:什么是一段逻辑代码:经过验证发现 if else 代码可以作为一段代码, for ()循环也可以作为一段代码,但是这种一段代码我们一般不会将{}省略,我们在使用过程中,函数体中只有一行代码且只有一段逻辑时,我们采取省略{} *优化后:* ```scala def func1 () = "China" ``` **3.4 形参列表()省略** *省略原则:当形参列表中没有参数时,可以省略()* ``` 3. () : 形参列表 ``` 优化后 ```scala def func1 = "China" ``` 说明:声明函数和调用函数是否需要带'()' > 1. 如果声明的函数没有(),那么调用函数时就一定不能有; > 2. 如果声明的函数中有(),那么调用函数时就可以有也可以没有。 特例:如果是将函数以对象的方式赋值给一个变量,那么通过变量调用函数时,()不能省去。 到此为止,是不是发现和变量声明方式及其相似,只是关键字不同。 ```scala def fun = "lilinchao博客" val name = "lilinchao博客" ``` **3.5 过程函数** return 与Unit 的区别 > 1. 假如返回值类型是Unit,并且显示定义了,那么函数体的return关键字不起作用。 > > 不起作用: 就是Unit不接收你return返回的数据,但是return依然可以起结束函数的作用。 > > 2. 之前说到return关键字可以省略,是因为return的地方一定是方法执行的最后一段代码'当然可能是多个位置,如条件表达式,不知道走哪个分支,但是每个分支如果执行,都是函数执行的最后一段代码'。 > > 如果我们显示的声明了return关键词,你的返回值类型就不能省略。 **由此引出了过程函数的概念** 显示声明return,希望返回值是Unit,但又不想显示声明Unit,那么怎么办? 采取省略 `=` 等号的方式实现这个需求。这样的函数,咱们就称为是过程函数。 代码如下 ```scala def fun {return "zhangsan "} ``` 此处的`{}`不能省略,此时return可以用来改变逻辑分支使用。 **3.6 匿名函数** 定义:当只关心代码逻辑,不关心函数名称时,函数名称和def关键字均可以省略,此时,这个函数没有名称和关键字,咱们就称这种函数为匿名函数。 *匿名函数的格式:* > (形参类表) => { 代码逻辑 } 如果代码逻辑只有一行,那么 {} 是可以省略的。 ```scala () => println("zhangsan") ``` 匿名函数调用:将匿名函数作为一个对象赋值给一个变量。 示例 ```scala val function = () => println("zhangsan") // 调用函数 function() ``` 注意事项: ```scala () => println("zhangsan") //将匿名函数赋值给一个变量 val function = () => println("zhangsan") // 调用函数 function() ``` *如上代码是不会被执行的。* *原因是:第一行代码的匿名函数,因为没有变量来进行接收,那么在编译的过程中,编译器会将匿名函数及后续所有代码编译成一个匿名函数,因为匿名函数在编译中没有被调用,所以被编译到匿名函数中的代码是不会被执行的。* ### 四、函数的高阶用途 **4.1 函数作为值** *函数可以作为对象赋值给变量。* 一共有两种方式: ```scala def function1 (name : String , age : Int ) : String = "name=" + name + ",age=" + age //方式一:使用 "函数名 _" 的方式 val func = function1 _ println(func("zhangsan", 20)) //方式二:指明变量的类型 //函数类型为:(参数列表每个参数的类型) => 返回值类型 val func1 : (String,Int) => String = function1 println(func1("zhangsan", 20)) ``` *特别注意* `val func = function1` 如果没有下划线也没有指明变量的类型,如果右边的函数无参的,则是将计算结果赋值给左边的变量,如果右边的函数有参数的,则直接报错。 **4.2 函数作为参数** 将封装好逻辑的函数,作为参数传递到其他函数中。 格式: > 函数名(函数名1:函数类型1,函数名2 : 函数类型) 代码示例 ```scala //准备一个基本函数1 def functions (i : Int) :Unit = println("age=" + i ) //将函数赋值给一个参数 val func = functions _ //准备另外一个函数2 def functions1 (f : Int => Unit , name : String) = f(10) //调用函数2,并将函数1传入 functions1(func,"zhangsan") ``` 注意事项: 我们也可以不声明变量,使用函数名的方式将函数直接传入,此时加和不加下划线都是可以的 ```scala functions1(functions,"zhangsan") functions1(functions _ ,zhangsan") ``` + 简化 将函数作为参数传递到另外一个函数中时,如果不关心函数的名称,则此时我们可以使用匿名函数的方式。 > *匿名函数: (形参列表) => {函数体}* 示例代码 ```scala (i:Int) => {println("age=" + i )} //准备另外一个函数 def functions1 (f : Int => Unit , name : String) = f(10) //调用函数,并将匿名函数传入 functions1((i:Int) => {println("age=" + i )},"zhangsan") ``` + 至简原则 ```scala // 1. 如果匿名函数代码只有一行,则可以省略{} functions1((i:Int) => println("age=" + i ),"zhangsan") // 2. 如果匿名函数对象的参数类型可以推断出来时,那么匿名函数的参数类型可省略 functions1( (i) => println("age=" + i ),"zhangsan") // 3. 如果匿名函数的参数列表只有一个或者没有,那么小括号也可以省去 functions1( i => println("age=" + i ),"zhangsan") // 4. 如果匿名函数的函数体中的逻辑中只使用一次,则参数可以省略,并使用下划线代替执行的。 functions1( println("age=" + _ ),"zhangsan") ``` 原因:第一行代码的匿名函数,因为没有变量来进行接收,那么在编译的过程中,编译器会将匿名函数及后续所有代码编译成一个匿名函数,因为匿名函数在编译中没有被调用,所以被编译到匿名函数中的代码是不会被执行的。 *附:* *参考原文链接:https://blog.csdn.net/qq_39437513/article/details/108674551*
标签:
Hadoop
,
Spark
,
Scala
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/1222.html
上一篇
Scala总结(一)
下一篇
SpringBoot2.x整合百度UidGenerator
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
标签云
Shiro
LeetCode刷题
DataX
GET和POST
Quartz
Spark
Java编程思想
HDFS
FileBeat
Spring
JavaWEB项目搭建
nginx
MyBatis
JavaWeb
栈
Golang
Nacos
Spark RDD
JVM
Eclipse
Flink
机器学习
Spark SQL
Git
Thymeleaf
SpringCloud
稀疏数组
持有对象
ClickHouse
设计模式
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞