我正在研究一些工具,这些工具将被加载到标准repl或ammonite中。有没有办法组合包对象/导入,以便我不必在我的客户端导入scala.concurent.duration包?这是我重用隐式持续时间转换的唯一方法吗?
(是的,我知道包装我的工具的菊石脚本可以加载REPL的所有内容,但是菊石可能不是我使用包裹的唯一方式)
这不是一种可扩展的方法:(
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)
}
}
答案 0 :(得分:1)
是。人们要求"包装进口"以这种方式,但它不会那样工作。
另一个常见用例是导入语言含义:您必须重新定义包中的值。
以下在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
用于一般初始化,但接缝较少的东西将是整洁的。