Scala传名参数(By-Name)

水深无声 2022-08-18 15:13 192阅读 0赞

1.=>

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

1.对于值,“=>”相当于lambda表达式。如:

  1. scala> List(1,2,3).map{(x: Int) => x*2}
  2. res0: List[Int] = List(2, 4, 6)

2.对于类型,“=>”两端的类型(如,A => B、(A, B) => C等)。它对于Function[A[, B…], T]是一个语法糖。一个函数传入参数是A[, B…],并且返回一个T类型的值。如:

  1. scala> val test: Function1[Int,String] = myInt => "my int: " + myInt.toString
  2. test: Int => String = <function1>
  3. scala> test(1)
  4. res0: String = my int: 1
  5. scala> val test: Int => String = myInt => "my int: "+ myInt.toString
  6. test: Int => String = <function1>
  7. scala> test(1)
  8. res1: String = my int: 1
  • 如果参数为空,即“=>”左边为空,形式是:() => T。如
  • scala> val test: Function0[String] = () => “Hello”
    test: () => String =

    scala> test()
    res3: String = Hello

    scala> val test: () => String = () => “Hello”
    test: () => String =

    scala> test()
    res4: String = Hello

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

    scala> test(1)
    1

  • 如果无参且无返回值,即“=>”两边都为空,形式是:() => Unit
  • scala> val test: Function0[Unit] = () => println(“Hello”)
    test: () => Unit =

    scala> test()
    Hello

    scala> val test: () => Unit = () => println(“Hello”)
    test: () => Unit =

    scala> test()
    Hello

**3.如果作为一个函数的参数的类型声明,且左边没有任何符号,如def func(param: => T)。这种形式叫做By-Name parameter。

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

2.By-Name Parameter

By-Value参数,我们都比较熟悉,参数在进入函数前就进行计算,最后传入的最终的计算结果。
By-Name参数,表示参数在进入函数后,每次在函数体内调用的时候才会计算。

  1. def myByName1(param: () => Boolean): Unit = {
  2. println("start")
  3. println(param) //println(param.apply())也可以
  4. println("end")
  5. }
  6. //要实现传名函数,要定义的类型开始于“=>”,而不是“() =>”。
  7. //myByName1{7>9}不会有效,因为缺少“() =>”
  8. myByName1{() =>
  9. println("enter")
  10. 7 > 9
  11. }

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

  1. start
  2. enter
  3. false
  4. end

再看下一种情况,只有“() =>”之后的代码是By-Name参数。“() =>”之前的代码是By-Value参数,即当调用myByName2的时候就会立即执行:

  1. def myByName2(param: () => Boolean): Unit = {
  2. println("start")
  3. println(param) //println(param.apply())也可以
  4. println("end")
  5. }
  6. myByName2{
  7. println("enter")
  8. () => 7 > 9
  9. }

输出如下:

  1. enter
  2. start
  3. false
  4. end

下面来看标准的By-Name参数:

  1. def myByName(param: => Boolean): Unit = {
  2. println("start")
  3. println(param)
  4. println("end")
  5. }
  6. myByName{
  7. println("enter")
  8. 7 > 9}

3.函数作为参数

By-Name有点像把函数作为参数的意思,但是实际上却不是。这里看下把函数作为参数的形式:

  1. def test(num: Int => String, str: String => Int): Unit = {
  2. val i = 10
  3. val s = "5"
  4. println(num(i))
  5. println(str(s))
  6. }
  7. def num(x: Int): String = {
  8. x.toString()
  9. }
  10. def str(s: String): Int = {
  11. s.toInt
  12. }
  13. test(num, str)

参考文献:

http://stackoverflow.com/questions/6951895/what-does-and-mean-in-scala

发表评论

表情:
评论列表 (有 0 条评论,192人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Scala 值调用和调用

    传值调用时,参数只在调用时计算一次,后续重复使用计算的结果 传名调用时,参数在调用时不会计算,只有真正用到参数的时候才会计算(x:=> Int) object S

    相关 Scala类型参数(一)

    Scala类型参数(一) 类型参数是对泛型的范围进一步的界定,那么介绍类型参数之前先聊聊泛型。Scala类型参数。类型参数是对泛型的范围进一步的界定,那么介绍类型参数之前

    相关 Scala类型参数

      类型参数是什么?  类型参数其实就类似于Java中的泛型。也是定义一种类型参数,比如在集合,在类,在函数中, 定义类型参数,然后就可以保证使用到该类型参数的地方,就