李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
大数据
正文
Scala总结(二)--函数
Leefs
2021-03-10 PM
1779℃
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
NLP
4
标签云
DataX
pytorch
Http
Typora
人工智能
Jquery
Spark SQL
Java编程思想
算法
GET和POST
Linux
FileBeat
Jenkins
Thymeleaf
设计模式
Elasticsearch
持有对象
Eclipse
RSA加解密
Livy
Hive
Netty
Spark Core
国产数据库改造
Stream流
Java
SQL练习题
SpringCloud
Azkaban
LeetCode刷题
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭