# Scala 函数

Scala 函数传名调用(call-by-name)

Scala的解释器在解析函数参数(function arguments)时有两种方式:

  • 传值调用(call-by-value):先计算参数表达式的值,再应用到函数内部;
  • 传名调用(call-by-name):将未计算的参数表达式直接应用到函数内部

在进入函数内部前,传值调用方式就已经将参数表达式的值计算完毕,而传名调用是在函数内部进行参数表达式的值计算的。

这就造成了一种现象,每次使用传名调用时,解释器都会计算一次表达式的值。

object Test{
    
    val f = (x: Int) => x+3
    def m(x:Int) = x + 3 
	def main(args:Array[String]){
		delayed(time())
	}
	
	def time() = {
		println("获取时间,单位为纳秒")
		System.nanoTime
	}
	
	def delayed(t: => Long) {  // 使用=> 符号来设置传名调用
	   println("在 delayed 方法内")
       println("参数: " + t)
       t
	}
	
}

指定函数参数名

一般情况下函数调用参数,就按照函数定义时的参数顺序一个个传递。但是我们也可以通过指定函数参数名,并且不需要按照顺序向函数传递参数,实例如下:

object Test {
  def main(args: Array[String]) {
    printInt(b = 5, a = 7)
  }

  def printInt(a:Int,b:Int) = {
    println("Value of a : " + a)
    println("Value of b : " + b)
  }
}

运行结果:
Value of a : 7
Value of b : 5

可变参数

Scala 允许你指明函数的最后一个参数可以是重复的,即我们不需要指定函数参数的个数,可以向函数传入可变长度参数列表。

Scala 通过在参数的类型之后放一个星号来设置可变参数(可重复的参数)。例如:

object Test {
   def main(args: Array[String]) {
        printStrings("Runoob", "Scala", "Python");
   }
   def printStrings( args:String* ) = {
      var i : Int = 0;
      for( arg <- args ){
         println("Arg value[" + i + "] = " + arg );
         i = i + 1;
      }
   }
}

高阶函数

高阶函数就是操作其他函数的函数

Scala 中允许使用高阶函数,高阶函数可以使用其他函数作为参数,活着使用函数作为输出结果

以下实例中,apply() 函数使用了另外一个函数 f 和 值 v 作为参数,而函数 f 又调用了参数 v:

object Test {
  def main(args: Array[String]) {
    println(apply(layout, 10))
  }

  def apply(f: Int => String, v: Int) = f(v)

  def layout[A](x: A) = "[" + x.toString + "]"
}

函数嵌套

我们可以在Scala 函数内定义函数,定义在函数内部的函数称为局部函数

object Test {
  def main(args: Array[String]) {
    println( factorial(0) )
    println( factorial(1) )
    println( factorial(2) )
    println( factorial(3) )
  }

  def factorial(i: Int): Int = {
    def fact(i: Int, accumulator: Int): Int = {
      if (i <= 1) {
        accumulator
      } else {
        fact(i - 1, i * accumulator)
      }
    }

    fact(i, 1)
  }
}

匿名函数

Scala 中定义匿名函数很简单,箭头左边是参数列表,右边是函数体

var inc =(x:Int) => x+2
var x = inc(7)-1
var mul = (x:Int,y:Int) => x * y
println(mul(3, 4))

object Demo {
   def main(args: Array[String]) {
      println( "multiplier(1) value = " +  multiplier(1) )
      println( "multiplier(2) value = " +  multiplier(2) )
   }
   var factor = 3
   val multiplier = (i:Int) => i * factor
}

Scala 偏应用函数

Scala 偏函数是一种表达式,不需要提供行数的所有参数,只需要部分参数,或不需要参数

import java.util.Date

object Test {
   def main(args: Array[String]) {
      val date = new Date
      log(date, "message1" )
      Thread.sleep(1000)
      log(date, "message2" )
      Thread.sleep(1000)
      log(date, "message3" )
   }

   def log(date: Date, message: String)  = {
     println(date + "----" + message)
   }
}


import java.util.Date

object Test {
  def main(args: Array[String]) {
    val date = new Date
    val logWithDateBound = log(date, _ : String) //第二个参数使用下划线(_)替换缺失的参数列表,并把这个新的函数值的索引的赋给变量。

    logWithDateBound("message1" )
    Thread.sleep(1000)
    logWithDateBound("message2" )
    Thread.sleep(1000)
    logWithDateBound("message3" )
  }

  def log(date: Date, message: String)  = {
    println(date + "----" + message)
  }
}

柯里化函数

柯里化(Currying)指的是将原来接收俩个参数的行数编程了接收一个参数函数的过程。新的函数返回一个以原有第二个参数为参数的函数。

object Test {
   def main(args: Array[String]) {
      val str1:String = "Hello, "
      val str2:String = "Scala!"
      println( "str1 + str2 = " +  strcat(str1)(str2) )
   }

   def strcat(s1: String)(s2: String) = {
      s1 + s2
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值