函数的定义

在Scala中定义函数需要使用 def 关键字,函数包括函数名参数函数体
Scala要求必须给出函数所有参数的类型,但是函数返回值的类型不是必须的,因为Scala可以自己根据函数体中的表达式推断出返回值类型。
Scala函数中最后一行代码的返回值就是整个函数的返回值,不需要使用return。这一点与Java不同,java中函数的返回值是必须要使用return的。

示例

1、无返回值

Unit表示无返回值

  1. def sayHello1(name: String): Unit = {
  2. println("hello," + name)
  3. }
  4. def main(args: Array[String]): Unit = {
  5. sayHello1("scala")
  6. }

image.png

2、有返回值

最后一行代码的返回值就是整个函数的返回值,不需要使用return

  def sayHello2(name: String, age: Int): Int = {
    println("hello," + name + ",age is " + age)
    100
  }

  def main(args: Array[String]): Unit = {
    println(sayHello2("zl", 27))
  }

image.png

3、给参数默认值

在Scala中,有时候我们调用某些函数时,不希望给出参数的具体值,而是希望使用参数自身默认的值,此时就需要在定义函数时使用默认参数。
如果给出的参数不够,则会从左往右依次应用参数。

  def sayHello3(fName: String, mName: String = "mid", lName: String = "last"): String = {
    fName + " " + mName + " " + lName
  }

  def main(args: Array[String]): Unit = {
    println(sayHello3("zhang", "san"))
  }

image.png
大家还记得Java中实现默认参数该怎么实现吗?
假设是要设置name和age这两个参数的默认值
java的写法:

public void sayHello(String name, int age) {     
  if(name == null) {     
    name = "defaultName"     
  }     
  if(age == 0) {     
    age = 18     
  }     
  System.out.println("Hello, " + name + ", your age is " + age)     
}

Scala的写法:

def sayHello(name: String ="defaultName" , age: Int = 18) {     
  println("Hello, " + name + ", your age is " + age)     
}

4、带名参数

在调用函数时,也可以不按照函数定义的参数顺序来传递参数,而是使用带名参数的方式来传递。

  def sayHello4(fName: String, mName: String = "mid", lName: String = "last"): String = {
    fName + " " + mName + " " + lName
  }

  def main(args: Array[String]): Unit = {
    println(sayHello4(fName = "Mick", lName = "Tom", mName = "Jack"))
  }

image.png

5、可变参数

参数个数可变的形式

  def sum(nums: Int*): Int = {
    var res = 0
    for (num <- nums) {
      res += num
    }
    res
  }

  def main(args: Array[String]): Unit = {
    println(sum(1, 2, 3, 4, 5))
  }

image.png

lazy

Scala提供了lazy特性,如果将一个变量声明为lazy,则只有在第一次使用该变量时,变量对应的表达式才会发生计算
什么场景下需要使用lazy特性呢?
这种特性对于特别耗时的操作特别有用,比如打开文件这个操作。

object FunctionDemo2 {

  lazy val lines = fromFile("D://test.txt").mkString

  def main(args: Array[String]): Unit = {
    lines
  }

}

即使D://test.txt文件不存在,代码也不会报错,只有变量使用时才会报错,这就是lazy这个特性。
image.png