繁体   English   中英

隐式类中的Scala按名称调用构造函数参数

[英]Scala call-by-name constructor parameter in implicit class

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

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类。

提前致谢。

彼得·施米茨的解决方案,简单地丢弃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的情况下,这在代码中并不明显,但无论如何都将在幕后发生)。 如果您也想删除此包装,我相信唯一的解决方案是使用宏。

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

implicit class RichElapsed[A](f: => A)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM