簡體   English   中英

Scala組成包對象

[英]Scala composing package objects

我正在研究一些將在標准repl或ammonite中加載的工具。 有什么方法可以組合包對象/導入,以便我不必在客戶中導入scala.concurent.duration包嗎? 這是我重用隱式持續時間轉換的唯一方法嗎?

(是的,我知道包裝工具的ammonite腳本可以為REPL加載所有內容,但是ammonite可能不是我使用軟件包的唯一方法)

這不是一個可擴展的方法:(

package object tool package {
  // redeclaring the implicit value class conversions found in package object scala.concurrent.duration
  implicit final class DurationInt(private val n: Int) extends AnyVal with DurationConversions {
    override protected def durationIn(unit: TimeUnit): FiniteDuration = Duration(n.toLong, unit)
  }

  implicit final class DurationLong(private val n: Long) extends AnyVal with DurationConversions {
    override protected def durationIn(unit: TimeUnit): FiniteDuration = Duration(n, unit)
  }
}

是。 人們要求以這種方式“打包進口商品”,但這種方式行不通。

另一個常見用例是導入語言隱式:您必須重新定義包中的值。

以下內容在REPL中不起作用,但請注意以下內容:

scala> :pa -raw
// Entering paste mode (ctrl-D to finish)

// attempt to add an import into the block
package object w {
  def wrap[A](a: A): A = macro www[A]
  import reflect.macros.blackbox.Context
  def www[A: c.WeakTypeTag](c: Context)(a: c.Expr[A]) = {
    import c.universe._
    val Block(ss, res) = a.tree
    Block(q"import scala.concurrent.duration._" +: ss, res)
  }
}

// Exiting paste mode, now interpreting.


scala> $intp.setExecutionWrapper("w.wrap")

它不起作用,因為包裝器包裝了錯誤的代碼位...

scala> 5.seconds
<console>:12: error: value seconds is not a member of Int
       5.seconds
         ^

scala> :se -Xprint:typer

scala> 42
[[syntax trees at end of                     typer]] // <console>
package $line7 {
  object $read extends scala.AnyRef {
    def <init>(): $line7.$read.type = {
      $read.super.<init>();
      ()
    };
    object $iw extends scala.AnyRef {
      def <init>(): type = {
        $iw.super.<init>();
        ()
      };
      object $iw extends scala.AnyRef {
        def <init>(): type = {
          $iw.super.<init>();
          ()
        };
        private[this] val res4: Int = 42;
        <stable> <accessor> def res4: Int = $iw.this.res4
      }
    }
  }
}

[[syntax trees at end of                     typer]] // <console>
package $line7 {
  object $eval extends scala.AnyRef {
    def <init>(): $line7.$eval.type = {
      $eval.super.<init>();
      ()
    };
    lazy private[this] var $result: Int = _;
    <stable> <accessor> lazy def $result: Int = {
      $eval.this.$result = $line7.$read.$iw.$iw.res4;
      $eval.this.$result
    };
    lazy private[this] var $print: String = _;
    <stable> <accessor> lazy def $print: String = {
      $eval.this.$print = ({
        import scala.concurrent.duration._;
        $line7.$read.$iw.$iw;
        "res4: Int = ".+(scala.runtime.ScalaRunTime.replStringOf($line7.$read.$iw.$iw.res4, 1000))
      }: String);
      $eval.this.$print
    }
  }
}

res4: Int = 42

...而且無論如何,代碼必須在擴展之前和之后進行編譯。

模板不允許添加尾括號:

scala> $intp.setExecutionWrapper("{ import scala.concurrent.duration._ ")

它必須看起來像

scala> $intp.setExecutionWrapper("{ import scala.concurrent.duration._ %s }")

正如您所指出的那樣, scala -i my-imports.sc用於常規init,但是接縫較少的東西會很整潔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM