[英]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.