【问题标题】:Function literal in Scala using valScala中的函数文字使用val
【发布时间】:2018-04-21 15:30:00
【问题描述】:

在以下代码中:

scala> val double = (i: Int) => {
|     println("I am here")
|     i * 2
|   }
double: Int => Int = $$Lambda$1090/773348080@6ae9b2f0

scala> double(4)
I am here
res22: Int = 8

scala> val evenFunc: (Int => Boolean) = {
|                   println("I am here");
|                    (x => x % 2 == 0)
|              }
I am here
evenFunc: Int => Boolean = $$Lambda$1091/373581540@a7c489a

scala> double
res23: Int => Int = $$Lambda$1090/773348080@6ae9b2f0

scala> evenFunc
res24: Int => Boolean = $$Lambda$1091/373581540@a7c489a

scala> evenFunc(10)
res25: Boolean = true

scala> def incr(x:Int) = x+1
incr: (x: Int)Int

scala> incr
<console>:13: error: missing argument list for method incr
Unapplied methods are only converted to functions when a function type is 
expected.
You can make this conversion explicit by writing `incr _` or `incr(_)` 
instead of `incr`.
incr

double 和 evenFunc 是函数变量,我们已经为它们分配了函数字面量。但是正如输出所示,当我们调用 double 时,也会执行 println 语句。但是 evenFunc 不执行 println 语句,除非在定义时。 incr 是用关键字 def 定义的,所以它的行为符合预期。

为什么 double 和 evenFunc 的行为不同,即使它们都引用函数字面量?

【问题讨论】:

    标签: scala function


    【解决方案1】:

    接收输入参数的点就是枢轴。

    如果您将evenFunc 从...更改为...

    println("I am here")
    x => x % 2 == 0
    

    ...到...

    x =>
    println("I am here")
    x % 2 == 0
    

    ...您将获得与 double 观察到的相同行为。

    在定义函数的地方评估/执行接收到的参数之前发生的事情。每次调用函数时执行接收到的参数之后会发生什么。

    【讨论】:

    • 我们从哪里知道这些规则?
    • 它可能在language spec 的某个地方,但我只是通过玩弄它发现了这个规则。
    【解决方案2】:

    区别很明显

    (i: Int) => {
         println("I am here")
         i * 2
     }
    
    {
       println("I am here");
       (x => x % 2 == 0)
    }
    

    函数字面量定义为(param list) =&gt; body。因此,第二个中的 println 语句在函数文字之前和之后进行评估,因此它不是函数体的一部分。

    【讨论】:

      猜你喜欢
      • 2014-10-07
      • 2018-03-15
      • 2021-04-15
      • 2013-11-05
      • 1970-01-01
      • 2011-05-25
      • 1970-01-01
      • 2015-08-07
      • 1970-01-01
      相关资源
      最近更新 更多