大数据之脚踏实地学14--Scala自定义函数

2019-05-21 23:15:40 浏览数 (1)

还没关注?

快动动手指!

前言

函数,其最大的好处在于避免了代码的重复编写,可以使编程过程更加地高效。尽管在《大数据之脚踏实地学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

长按扫码关注我

0 人点赞