还没关注?
快动动手指!
前言
函数,其最大的好处在于避免了代码的重复编写,可以使编程过程更加地高效。尽管在《大数据之脚踏实地学12--Scala数据类型与运算符》和《大数据之脚踏实地学13--Scala控制流》一文中我们都使用了Scala的函数,但没有详细介绍函数的具体使用方法和注意细节。本文我们将详细介绍Scala函数的相关知识点。
函数语法
代码语言:javascript复制def func_name(parameter: dtype) : return_dtype = {
func_body
return
}
def:为自定义函数的关键词,不可少; func_name:自定义函数的具体名称,不可少; parameter:参数名称,如果函数没有参数,括号内可以不写任何东西; dtype:参数的数据类型,参数名和数据类型之间用冒号隔开,如果函数包含多个参数,则参数之间用逗号隔开,如"p1:Int,p2:String"; return_dtype:指定函数的值返回类型,如果没有具体的返回值,return_dtype可以写成Unit,如果": return_dtype"不写,则函数自推数据类型(如果自定义的是递归函数,return_dtype必须要写); func_body:函数体; return:需要返回的函数值,可以写在return关键词后面,但绝大多数情况,return关键词可以不用写;
使用Scala编写代码块,需要首先构建一个对象object,然后再将主函数、类以及其他自定义函数封装在这个object中。具体语法如下:
代码语言:javascript复制// 构造对象
object Test {
// 主函数,可以调用自定义函数,还可以做其他运算
def main(args: Array[String]): Unit = {
expression
}
// 自定义函数
def func_name(parameter: dtype) : return_dtype = {
func_body
return
}
}
object:构造对象所使用的关键词; main:主函数的名称,只能写main,不能换做其他; args:主函数的参数,也是一种固定写法,当然也可以写成其他字符,如parms; Array[String]:主函数参数的数据类型,固定写法,表示字符型的数组;
函数的参数类型
熟悉Python的朋友,对函数也一定不陌生,在Python中自定义函数包含四类参数,分别是必选参数、默认参数、可变参数和关键字参数。在Scala中也有不同的参数类型,不同的是,其没有关键字参数。接下来我们通过几个小案例,分别介绍必选参数、默认参数和可变参数。
必选参数
必选参数,顾名思义就是当你在调用一个自定义函数时,必选给函数中的一些参数赋值,否则程序将会报错,并提醒用户“函数缺少参数值”。如下举例,构造一个计算两个数乘积的算法平方根的自定义函数。
举例
代码语言:javascript复制// 导入第三方包
import scala.math
object Test01 {
def main(args: Array[String]): Unit = {
val x1 = 10.37
val x2 = 8
// 调用函数
printf(x1 "与" x2 "乘积的算法平方根为%.2f",mul_root(x1,x2))
}
// 自定义两个数乘积的算法平方根
def mul_root (x1 : Double, x2 : Double) = {
val res = math.sqrt(x1 * x2)
res
}
}
输出结果为:10.37与8乘积的算法平方根为9.11
默认参数
默认参数比较好理解,就是在自定义函数的同时,某些参数就已经赋予了初始值。如下举例,计算两个数和的平方。
代码语言:javascript复制object Test02 {
def main(args: Array[String]): Unit = {
val x1 = 21.7
val x2 = 13.6
// 调用函数
printf(x1 "与" x2 "和的平方为:%.2f", sum_square(x1,x2))
}
// 自定义两个数和的平方,其中p参数为默认参数
def sum_square (x1 : Double, x2 : Double, p : Int = 2) = {
val res = math.pow((x1 x2), p)
res
}
}
当自定义函数中既有必选参数,又有默认参数时,给函数传递的参数最好使用名称参数的方式,即parm_name = value。
举例
代码语言:javascript复制import scala.io.StdIn
object Test03 {
def main(args: Array[String]): Unit = {
println("请输入用户名:")
val user = StdIn.readLine()
println("请输入密码:")
val passwd = StdIn.readLine()
// 调用函数
mysqlConnect(user = user, passwd = passwd)
}
// 自定义函数
def mysqlConnect(host: String = "172.0.0.1", user: String,
passwd: String, port: Int = 3306) = {
if (user == "mysql" && passwd == "mysql123") {
println("恭喜您,数据库连接成功!")
} else {
println("对不起,用户名或密码错误!")
}
}
}
在如上代码中,主函数中调用mysqlConnect函数时,就必须使用名称参数,否则user值和passwd值将默认传递给host参数和user参数,很显然这是错的。
可变参数
上面讲解的必选参数和默认参数,都是在已知这个自定义函数需要多少个形参的情况下构建的。那如果我不确定该给这个函数传入多少个参数的时候,该怎样自定义函数呢?这么说可能有点抽象,我们举个对比的例子来说明。小明的弟弟小亮刚读高中,老师布置了一些关于两个数和的平方,针对这个问题,我们可以调用如上介绍的sum_square函数。
但如果不是两个数和的平方,而是三个数、四个数或五个数和的平方呢?那这个时候,在不确定计算几个数和的平方的情况下,sum_square函数就不能使用了。好在Scala给自定义函数提供了可变参数,目的就是解决这类问题的。举例如下:
代码语言:javascript复制object Test04 {
def main(args: Array[String]): Unit = {
// 调用函数
println("这些数字和的平方为:" sum_square_new(10,24,12,15,33,26,15,21,27))
}
// 自定义含可变参数的函数
def sum_square_new(args : Int*): Double = {
var sum = 0
for (i <- args) {
sum = i
}
val res = math.pow(sum,2)
res
}
}
看见了吧,这个可变参数就可以接受任意多个数值,需要注意的是,用一颗星“*”放在参数的类型后面,就代表了该参数为可变参数。一个可变参数之所以可以接受多个数值,起背后的原理是将这些输入的数值进行了一次捆绑,即组装到一个集合中。
结语
本期的内容就介绍到这里,如果你有任何问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位朋友继续转发与分享文中的内容,让更多的人学习和进步。
每天进步一点点:数据分析1480
长按扫码关注我