簡體   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