Scala传名参数(By-Name)

来源:互联网 发布:淘宝评价怎么不能晒图 编辑:程序博客网 时间:2024/06/05 23:08

1.=>

在了解Scala的By-Name参数之前,先了解下“=>”在Scala中有几种用法:

1.对于值,“=>”相当于lambda表达式。如:
scala> List(1,2,3).map{(x: Int) => x*2}res0: List[Int] = List(2, 4, 6)

2.对于类型,“=>”两端的类型(如,A => B、(A, B) => C等)。它对于Function<n>[A[, B...], T]是一个语法糖。一个函数传入参数是A[, B...],并且返回一个T类型的值。如:
scala> val test: Function1[Int,String] = myInt => "my int: " + myInt.toStringtest: Int => String = <function1>scala> test(1)res0: String = my int: 1scala> val test: Int => String = myInt => "my int: "+ myInt.toStringtest: Int => String = <function1>scala> test(1)res1: String = my int: 1

  • 如果参数为空,即“=>”左边为空,形式是:() => T。如
  • scala> val test: Function0[String] = () => "Hello"test: () => String = <function0>scala> test()res3: String = Helloscala> val test: () => String = () => "Hello"test: () => String = <function0>scala> test()res4: String = Hello

  • 如果无返回值,即“=>”右边为空,形式是:A[, B...] => Unit
  • scala> val test: Int => Unit = myInt => println(myInt)test: Int => Unit = <function1>scala> test(1)1

  • 如果无参且无返回值,即“=>”两边都为空,形式是:() => Unit
  • scala> val test: Function0[Unit] = () => println("Hello")test: () => Unit = <function0>scala> test()Helloscala> val test: () => Unit = () => println("Hello")test: () => Unit = <function0>scala> test()Hello
3.如果作为一个函数的参数的类型声明,且左边没有任何符号,如def func(param: => T)。这种形式叫做By-Name parameter。

4.在case语句中,“=>”用于分隔模式和结果表达式。

2.By-Name Parameter

By-Value参数,我们都比较熟悉,参数在进入函数前就进行计算,最后传入的最终的计算结果。
By-Name参数,表示参数在进入函数后,每次在函数体内调用的时候才会计算。
def myByName1(param: () => Boolean): Unit = {    println("start")    println(param)      //println(param.apply())也可以    println("end")  }  //要实现传名函数,要定义的类型开始于“=>”,而不是“() =>”。//myByName1{7>9}不会有效,因为缺少“() =>”myByName1{() =>     println("enter")    7 > 9}

其中“=>”后面的代码是整体作为参数,所以会在函数体里被调用的时候才会执行。输出如下:
startenterfalseend

再看下一种情况,只有“() =>”之后的代码是By-Name参数。“() =>”之前的代码是By-Value参数,即当调用myByName2的时候就会立即执行:
def myByName2(param: () => Boolean): Unit = {    println("start")    println(param)    //println(param.apply())也可以    println("end")  }    myByName2{    println("enter")    () => 7 > 9  }

输出如下:
enterstartfalseend

下面来看标准的By-Name参数:
def myByName(param: => Boolean): Unit = {    println("start")    println(param)    println("end")  }    myByName{    println("enter")    7 > 9}

3.函数作为参数

By-Name有点像把函数作为参数的意思,但是实际上却不是。这里看下把函数作为参数的形式:
def test(num: Int => String, str: String => Int): Unit = {    val i = 10    val s = "5"    println(num(i))    println(str(s))  }    def num(x: Int): String = {    x.toString()  }    def str(s: String): Int = {    s.toInt  }    test(num, str)


参考文献:
http://stackoverflow.com/questions/6951895/what-does-and-mean-in-scala

0 0
原创粉丝点击