2

以下代码无法编译。希望在隐式类中有一个按名称调用的构造函数参数,如此处所示,

def f(n: Int) = (1 to n) product

implicit class RichElapsed[A](val f: => A) extends AnyVal {

  def elapsed(): (A, Double) = {
    val start = System.nanoTime()
    val res = f
    val end = System.nanoTime()

    (res, (end-start)/1e6)
  }

}

在哪里打电话

val (res, time) = f(3).elapsed
res: Int = 6
time: Double = 123.0

REPL中报这个错误,

<console>:1: error: `val' parameters may not be call-by-name
       implicit class RichElapsed[A](val f: => A) extends AnyVal {

因此要问如何RichElapsed重构类。

提前致谢。

4

2 回答 2

2

Peter Schmitz 的解决方案是简单地放弃val(以及希望RichElapsed变成一个价值类)当然是最简单和最少侵入性的事情。

如果你真的觉得你需要一个价值类,另一种选择是:

class RichElapsed[A](val f: () => A) extends AnyVal {

  def elapsed(): (A, Double) = {
    val start = System.nanoTime()
    val res = f()
    val end = System.nanoTime()

    (res, (end-start)/1e6)
  }
}

implicit def toRichElapsed[A]( f: => A ) = new RichElapsed[A](() => f )

请注意,虽然使用上面的值类允许删除临时RichElapsed实例的实例化,但仍有一些包装正在进行(使用我的解决方案和 Peter Schmitz 的解决方案)。也就是说,按名称传递的主体f被包装到一个函数实例中(在 Peter Schmitz 的情况下,这在代码中并不明显,但无论如何都会在幕后发生)。如果您也想删除此包装,我相信唯一的解决方案是使用宏。

于 2014-04-16T09:08:46.213 回答
1

val按照错误消息的要求执行此操作,然后您还必须放弃,AnyVal因为值类需要恰好有一个公共 val:

implicit class RichElapsed[A](f: => A)
于 2014-04-16T08:53:23.617 回答