Scala函数 表达式

本文介绍了Scala编程中的基本概念,包括函数的定义与使用,如默认参数、命名参数和可变参数。同时讲解了匿名函数、条件表达式、循环表达式和组合表达式的应用。此外,还探讨了函数作为对象的特性,展示了如何在Scala中创建和使用匿名函数。
摘要由CSDN通过智能技术生成

目录

函数的定义和使用

默认参数

命名参数

可变参数

作为对象的函数

匿名函数

条件表达式

循环表达式

组合表达式


 

函数的定义和使用

def 方法名(参数名:参数类型): 返回值类型 = {

      // 括号内的叫做方法体

     // 方法体内的最后一行为返回值,不需要return

}

  • 若有返回值, 方法体内的最后一行为返回值,不需要return
  • 若不要返回值,则返回值类型是Unit
  • = 后面是有{}的但是我们只有一行,{}可以不写
  • 若程序可以推断出返回值类型,则返回值类型也可以不写
  • scala的特别之处,方法没有入参,调用时()可以不写

object FunctionApp {
  def main(args: Array[String]): Unit = {
    println(add(1, 4))
    println(add())
    println(add) // scala的特别之处,方法没有入参,调用时()可以不写
    sayHello()
    sayHello("Amy")
  }

  def add(x: Int, y: Int): Int = {
    x + y // 最后一行就是返回值,不需要return语句
  }

  def add(x: Int): Int = x + 1 // = 后面是有{}的但是我们只有一行,可以不写
  def add() = 1 + 2 // 返回值类型也没有写,因为底层可以推断
  def sayHello(): Unit = println("Say hello ..... ")
  def sayHello(name: String) = println("Say hello ..... " + name)
}

默认参数

在函数定义的时候,允许指定默认值。但是默认参数,也是可以传入参的,所以,即使调用时不传参,()也不可以省略。

object FunctionApp {
  def main(args: Array[String]): Unit = {
    sayHello("xuanshuang")
//    sayName // 报错,尽管有默认值,可以不传参,但依旧有参数列表,()不可以省略
    sayName()
    sayName("Lily")
  }
  def sayHello(name: String) = println("Say hello ..... " + name)
//  def sayHello(name: String = "xuanshuang") = { //报错,sayHello已定义
//    println("Say hello ..... " + name)
//  }
  def sayName(name: String = "Amy") = println("Say hello ..... " + name)
}

命名参数

命名参数:在函数调用的时候可以不按照顺序传值,可以通过名字把值传给函数

  • 调用的时候可以以行参=xxx(命名参数)的方式传值,这样打乱顺序传值,也能正确运行
  • scala还可以在顺序传值的时候借用命名参数传值,与其他语言的区别之处,顺序传值后面的可以直接传值,不需要借助命名参数
  • 若非顺序传值,第一个命名参数之后都必须命名参数传值
  • 与默认参数组合使用时,命名参数显得更加有用
object FunctionApp {
  def main(args: Array[String]): Unit = {
    println(speed(100, 10, "Amy"))
    println(speed(100, time = 10, "Jack"))
//    println(speed(time =100, distance = 10, "palne")) //报错,Positional after named argument
    println(speed(distance=100, time = 10, "xs"))
  }
  def speed(distance: Float, time: Float, name: String )={
    name + "," + (distance / time)
  }
}

可变参数

  • 与Java一样,方法重载时,可变参数列表所在的方法是最后被访问的
  • 与Java一样,可变列表一定要放在最后。即不可以def concat(words: Char*, a: Int)
  • 正因为可变列表一定要放在最后,所以一个方法只能有一个可变参数
  • 命名参数和默认参数当前在可变参数列表组合使用时,有如下特性——无法修改命名参数的定义顺序,建议尽量避免组合使用命名参数和可变参数。
object FunctionApp {
  def main(args: Array[String]): Unit = {
    // 这边强转会将数字转成对应的ASII码代表的字符,
    println(concat(65.asInstanceOf[Char],'h', 'e', 'l', 'l', 'o'))
    println(concat())
    println(concat('h', 'e')) // 和Java类似,双参和可变参数的concat方法均能匹配时,优先匹配双参
  }
  def concat(words: Char*): String ={
    var result: String = "可变参数,result is :"
    for(word <- words){
      result += word
    }
    result
  }
  def concat(one: Char, two: Char) = "双参,result is :" + one + two
}
class Family(mom: String, dad: String, kids: String*)
object NamedDefaultFlexibleArgs {
  def main(args: Array[String]): Unit ={
    new Family(mom="mom", dad="dad")
    // Error:when using named arguments, the vararg parameter has to be specified exactly once
    //    new Family(dad="dad", mom="mom")
//命名参数和默认参数当前在可变参数列表组合使用时,有如下特性——无法修改命名参数的定义顺序
//    new Family(dad="dad", mom="mom")
  }
}

作为对象的函数

方法是依附于类或对象的,而函数是其自身的对象(这就是为啥我们可以如此容易的传递它)。当作参数传递给其他方法或函数的函数通常都非常小,且往往只使用一次。可以定义一个匿名函数。

  • 匿名函数时使用=>符号定义的,=>左边是参数列表,右边是单个表达式(可以是组合表达式)。
  • 若是多个参数,就必须对参数列表使用括号
  • 只有一个参数,且Scala可以推断出该参数的类型,则可以去掉括号和参数类型。
// Later类接受一个具有0个参数的函数作为参数,
// 使用匿名函数的方式定义的,无任何参数(),一个=>和Unit合起来
class Later(val f: () => Unit){
  def call():Unit = {f()}
}
object Anonymous {
  def main(args: Array[String]): Unit ={
    val v1 = Vector("hello", "Scala")
    // 匿名函数时使用=>符号定义的,=>左边是参数列表,右边是单个表达式(可以是组合表达式)
    v1.foreach((n: String) => {print(n + " -> ")})
    println()
    val v2 = Vector(1, 2, 3)
    // 只有一个参数,且Scala可以推断出该参数的类型,则可以去掉括号和参数类型。
    v2.foreach(n => print(n + " -> "))
    println()
    println("=========================")
    val later = new Later(() => println("now"))
    later.call()
    val later1 = ()=>println("hi")
    // 报错:later1() Unit does not take parameters
//    val later2 = println
//    later2()
  }
}

匿名函数

  • 匿名函数是使用=>符号定义的,=>左边是参数列表,右边是单个表达式(可以是组合表达式)
  • 只有一个参数,且Scala可以推断出该参数的类型,则可以去掉括号和参数类型。

我们在下面的例子中,

  • 将匿名函数以参数列表的形式传递给Later类,当该类的实例化对象调用call方法时会调用该匿名函数。其中若call(),则调用可以选择是否加括号,若call,调用时不能用括号
  • 在主函数中定义了函数def later1 = ()=>println("hi 1"),通过later1()可调用,later1没输出
  • val later2 = ()=>println("hi 2"),通过later2()调用,later2没输出
// Later类接受一个具有0个参数的函数作为参数,
// 使用匿名函数的方式定义的,无任何参数(),一个=>和Unit合起来
class Later(val f: () => Unit){
  def call():Unit = {f()}
}
object Anonymous {
  def main(args: Array[String]): Unit ={
    val v1 = Vector("hello", "Scala")
    // 匿名函数是使用=>符号定义的,=>左边是参数列表,右边是单个表达式(可以是组合表达式)
    v1.foreach((n: String) => {print(n + " -> ")})
    println()
    val v2 = Vector(1, 2, 3)
    // 只有一个参数,且Scala可以推断出该参数的类型,则可以去掉括号和参数类型。
    v2.foreach(n => print(n + " -> "))
    println()
    println("=========================")
    val later = new Later(() => println("now"))
    later.call()
    later.call
    def later1 = ()=>println("hi 1")
    later1()
    later1 // 没有输出

    val later2 = ()=>println("hi 2")
    later2 // 没有输出
    later2()

    val later3 = println
    later3 // 无输出
//    later3() // 报错:later3() Unit does not take parameters
  }
}

条件表达式

下例中,整个if就是一个表达式,因此它会产生一个结果

scala> val x = -1//x: Int = -1
scala> val a = if(x >0 )true else false //a: Boolean = false

循环表达式

  • to: 左闭右闭
  • range:左闭右开
  • until:左闭右开
object FunctionApp {
  def main(args: Array[String]): Unit = {
    for(i <- 1.to(5)) print(i + " ")
    println()
    for(i <- 1.until(5) if i % 2 == 0) print(i + " ")
    println()
    for(i: Int <- Range(5, 1, -2)) print(i + " ")
    println("\n=================================")

    val courses = Array("Hadoop", "Spark SQL", "Storm", "Scala", "Spark Streaming")
    for(course <- courses) print(course + " ")
    println()
    courses.foreach(print)
    println()

    //course 其实就是courses里面的每个元素
    // =>将左边的函数作用上一个函数变成另一个结果
    // print就是作用到course伤的一个函数
    courses.foreach(course => print(course + " "))
    println("\n=================================")

    var (num, sum) = (100, 0)
    while(num > 0){
      sum = sum + num
      num -= 1
    }
    println("100 + 99 + ... + 2 + 1 = " + sum)

  }
}

组合表达式

下例中组合表达式的结果作为isOpen的值,自然,类似println这样的表达式并不会产生结果,组合表达式也并非必须产生结果

val hour = 6
val isOpen={
    val opens = 9
    val closes = 20
    println("Operating hour: " + opens + " - " + closes)
    if(hour >= opens && hour <= closes){
        true
    }else{
        false
    }
}

 

 

参考:慕课网-学习Scala进击大数据Spark生态圈,收获高薪未来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值