因为Scala是一种函数式编程语言,因此在Scala中基本上都是方法和函数,但是需要注意的是,在Java中方法和函数是同一个意思,但是在Scala中函数和方法的含义不同:
在这一篇文章中我先来认识方法。
目录
普通的加减乘除等在Scala中都可以是方法,在Java中的加减乘除不是方法,而是一种运算符。光讲会有点枯燥,现在我使用代码来看一下在Scala中,运算符作为方法被调用的写法及效果。
我将让整型3加上双精度型3:
- scala> 3.+(3:Double) // 不管是什么计算机语言,默认输入的整数都是int类型,如果想要该数字为double类型可以指定类型为Double
- res4: Double = 6.0

Scala中方法的定义格式:
def 方法名([变量名1:变量类型,变量名2:变量类型]) :[返回值类型]={方法体}
解释:[]:方括号表示可有可无,是可选项。
因为Scala可以进行类型推断,所以返回值类型也可以省略,所以以上的定义格式也可以写成:
def 方法名([变量名1:变量类型,变量名2:变量类型])={方法体}
对于Scala中无参无返回值的方法来来说,参数列表是可以省略的。
现在我定义一个名为function的方法,并且无参无返回值:
scala> def function():Unit={println("我是一个无参无返回值的方法")}

- scala> def function=println("我是一个无参无返回值的方法")
- function: Unit

在上面,相信大家也发现了,在简写定义一个方法时,我把方法体外面的花括号给去掉了,但是调用方法之后还是依旧可以输出方法体的内容,这是为什么?主要是因为在Scala的方法中,如果方法体只有一条语句,那么方法体外面的花括号可以省略不写。但是如果有很多条的话就不能够省略,如下,此时的function方法体里面不再是简单的一条输出语句,还涉及到了一些逻辑运算,这个时候如果不加上花括号的话就会报错:
def function=val a=11;val b=23; println(s"我是一个无参无返回值的方法,方法中两个变量的和为${a+b}")

接着我加上了花括号之后就会正常输出:
def function={val a=11;val b=23; println(s"我是一个无参无返回值的方法,方法中两个变量的和为${a+b}")}

在Scala中默认是以最后一条语句作为返回值返回的,所以现在我将方法体里面的两个变量的和写在了方法体的最后一句,那么就会返回a+b的值,且这个时候方法function的返回值类型为Int类型:
def function={val a=11;val b=23; println(s"我是一个无参无返回值的方法,方法中两个变量的和为${a+b}");a+b}

并且在调用该方法的时候也会将a+b的结果作为方法function的返回值返回:

如果在方法体中写上了return关键字,就必须在参数列表的后面显式的指定方法的返回值,不然就会报错。

现在我加上了该方法的返回值后,结果如下:
def function:Int={val a=11;val b=23; println(s"我是一个无参无返回值的方法,方法中两个变量的和为${a+b}");return a+b}

总而言之,在Scala方法的定义中要不要写return关键字,看个人。
[我一般不写,反正有Scala虚拟机帮我进行数据类型的推断,就没啥必要去写了,还省事]。
相比于无参无返回值的方法,有参有返回值无非就是方法的参数列表中有参数不能省略,即使有返回值也可以不用写return,只需要将要返回的值写在方法体的最后一行即可。
现在我定义一个有两个Int类型的参数并且返回值为Int类型的方法function:
- /**
- * @author:码到成龚
- * my motoo:"听闻少年二字,应与平庸相斥。"
- * 个人代码规范:
- * 1,原始数据的变量命名:①只使用单个单词即数据的类型:无嵌套的数据结构②被嵌套的数据结构类型_嵌套的数据结构类型:嵌套的数据结构
- * 2,接收结果的变量命名:①包含的数据类型1_包含的数据类型2_返回的变量类型_表达式中使用到的函数1_表达式中使用到的函数2
- * 3,调用函数时的注释:①数据调用第一个函数输出的结果为:函数名-OUT;函数名-OUT....以此类推
- *
- */
- object Method1 {
- // 定义有参有返回值的方法
- def function(a:Int,b:Int)={ // 有参的方法
- println(s"a+b=${a+b}") // 用于打印变量a和变量b的和
- a+b // 返回值为Int类型
- }
- def main(args: Array[String]): Unit = {
- // 调用方法
- val ob=Method1 // 创建对象
- ob.function(22,33) // 使用对象来调用方法
- }
- }

方法的返回值得需要类或者是对象调用方法之后咋再去调用打印语句输出返回值,不然就不会有任何输出。上面我之所以有输出是因为我在方法体里面就写上了打印语句:

如果把这句打印语句注释掉,对象或者是类在调用方法function并且无任何打印,那么就会无任何输出:

当不确定要输入的参数有多少个的时候就可以定义一个带有可变参数的方法
格式:def 方法名(参数名:参数类型*):方法返回值={方法体}
可以看到,所谓的可变参数不过就是在参数类型的后面加上了*号而已。现在我使用具体的代码来查看具体的实现:

如上,我发现在带有可变参数的方法里面可以将传入的参数做一个遍历,来得到每一个参数,并且可以进行相关的操作。
递归的解释:程序调用自身的编程技巧称为递归。
在数学上也存在递归的现象,如:斐波那契数列,阶乘等。使用了递归的方法就称为递归方法。
接下来我使用几个案例结合递归的方法来解决问题
有八个人围坐在一起,问第八个人的年龄,他说比第七个人大两岁,之后去问第七个人的年龄,他比第六个人大两岁,以此类推,两个人之间相差的年龄为2。当问第一个的年龄是他说是10岁。问:第八个人几岁?
分析题目可知:每一个人的年龄都是上一个人的年龄加2得到,因此,可以使用2加上自身即可。

-
- /**
- * @author:码到成龚
- * my motoo:"听闻少年二字,应与平庸相斥。"
- * 个人代码规范:
- * 1,原始数据的变量命名:①只使用单个单词即数据的类型:无嵌套的数据结构②被嵌套的数据结构类型_嵌套的数据结构类型:嵌套的数据结构
- * 2,接收结果的变量命名:①包含的数据类型1_包含的数据类型2_返回的变量类型_表达式中使用到的函数1_表达式中使用到的函数2
- * 3,调用函数时的注释:①数据调用第一个函数输出的结果为:函数名-OUT;函数名-OUT....以此类推
- *
- */
- object Digui1 {
- /**
- * nu=1 :OUT=>10
- nu=2 :OUT=>2+function(1)=>2+10=>12
- nu=3 :OUT=>2+function(2)=>2+2+function(1)=>2+2+10=>14
- .
- .
- 以此类推
- num=8 :OUT=>2+function(7)=>2+2+function(6)=>2+2+2+function(5)=>2+2+2+2+function(4)=>2+2+2+2+2+function(3)
- * @param num 表示为第几个人
- * @return:返回值为int类型
- */
- def function(num:Int): Int ={ // 定义一个参数为int类型,返回值类型也为int的方法
- if (num==1) { // 第一个人的年龄
- 10
- }
- else{
- 2+function(num-1) // 返回2加上一个人的年龄
- }
- }
- def main(args: Array[String]): Unit = {
- println(Digui1.function(8)) // 使用类来调用方法,并调用prntln打印结果
- }
-
- }
该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。
形如:0 1 1 2 3 5 8 13 21 34.....function(n-1)+function(n-2)
请定义一个方法function(num:Int),并打印输出斐波那契数列的第九项:
,当num=9时,输出21

- /**
- * @author:码到成龚
- * my motoo:"听闻少年二字,应与平庸相斥。"
- * 个人代码规范:
- * 1,原始数据的变量命名:①只使用单个单词即数据的类型:无嵌套的数据结构②被嵌套的数据结构类型_嵌套的数据结构类型:嵌套的数据结构
- * 2,接收结果的变量命名:①包含的数据类型1_包含的数据类型2_返回的变量类型_表达式中使用到的函数1_表达式中使用到的函数2
- * 3,调用函数时的注释:①数据调用第一个函数输出的结果为:函数名-OUT;函数名-OUT....以此类推
- *
- */
- object DiGui2 {
- /**
- * 该数列由0和1开始,后面的每一项数字都是前面两项数字的和
- * @param num:表示第几个数
- * @return Int:返回值为int类型的数据
- */
- def function(num:Int): Int ={
- if(num==1){ // 如果传入的数字为0或者是1直接返回1
- 0
- }
- else if(num==2){
- 1
- }
- else {
- // 后一项为前两项相加之和
- function(num-1)+function(num-2)
- }
- }
- def main(args: Array[String]): Unit = {
- println(DiGui2.function(9))
- }
- }
兔子拔了一堆萝卜,第一天吃了一半,还嫌不过瘾,又吃了一个,第二天又将剩下的萝卜吃掉一半,又多吃了一个,以后每天如此.到第10天想再吃时,见只剩下一个萝卜了,求第一天共拔了多少萝卜.
个人分析【仅供参考】:
第十天:1
第九天:(1)*2+1
第八天:【(1)*2+1】*2+1
.
.
.
第一天:【第二天的萝卜数】*2+1即function(day+1)*2+1
现在我使用代码来查看具体的实现效果:

- /**
- * @author:码到成龚
- * my motoo:"听闻少年二字,应与平庸相斥。"
- * 个人代码规范:
- * 1,原始数据的变量命名:①只使用单个单词即数据的类型:无嵌套的数据结构②被嵌套的数据结构类型_嵌套的数据结构类型:嵌套的数据结构
- * 2,接收结果的变量命名:①包含的数据类型1_包含的数据类型2_返回的变量类型_表达式中使用到的函数1_表达式中使用到的函数2
- * 3,调用函数时的注释:①数据调用第一个函数输出的结果为:函数名-OUT;函数名-OUT....以此类推
- *
- */
- object DiGui3 {
- /**
- * @param day:第几天
- * @return:返回值为Int类型【萝卜数】
- */
- def function(day:Int):Int ={ // 定义一个方法
- if(day==10){
- 1
- }
- else {
- function(day+1)*2+1
- /*
- day=10 => function(10)=>1
- day=9 => function(9+1)*2+1 => function(10)*2+1 =>1*2+1=>3
- day=8 => function(8+1)*2+1 => function(9)*2+1=> function(9)=3 => 3*2+1=7
- .
- .
- .
- */
- }
- }
- def main(args: Array[String]): Unit = {
- println(DiGui3.function(1)) // 类来调用方法并向方法中传入参数值
- }
-
- }
请查找并打印出目录下的所有文件,如果是文件则直接打印出来,是目录的话就进行递归查找:

- import java.io.File // 导包
- /**
- * @author:码到成龚
- * my motoo:"听闻少年二字,应与平庸相斥。"
- */
- object FindFile {
- /**
- * findFile方法用于遍历指定目录下的文件,
- * 如果该目录下还有目录,则去递归找到子目录下的文件
- * @param file :需要传入文件对象
- */
- def findFile(file_object:File):Unit={
- // 如果为目录则就行递归,不是目录则不用进行递归
- if(file_object.isFile){ // isFile用于判断当前的文件对象是否是文件
- println(s"${file_object.getName}不是目录,无法进行递归") // getName方法用于获取当前文件对象的名字
- }
- else{
- val file_list=file_object.listFiles() // 得到文件列表
- for(file <- file_list){ // 遍历文件列表
- if (file.isFile){
- println(file)
- }else{
- findFile(file) // 是目录,就进行递归查找
- }
- }
- }
- }
- def main(args: Array[String]): Unit = {
- val file_object=new File("C:\\Program Files (x86)\\Common Files") // 创建文件对象
- findFile(file_object) // 直接调用方法
- }
- }
以上就是Scala中方法的基本内容,我的学习完成,有问题的欢迎在评论区留言。