so - 我在 scala 中使用了一个来自 java 的接口,该接口使用奇怪的重复出现的模板模式 - 它本质上是一个克隆函数:
interface Blah<T>
{
T clone();
}
这意味着如果你有一个很长的讨厌的班级,你必须做:
class LongNastyClass extends Blah[LongNastyClass]
{...}
但当然 scala 相当神奇 - 并且有宏和东西 - 所以我想知道它是否有可能(我想不出一种方法( - 将这种混乱隐藏在一个特征后面
例如 - 像这样:
trait BlahBetter extends Blah[this.type] {
}
这样任何使用它的人都不必知道他们应该指的是自己 - 例如:
class LongNastyClass extends BlahBetter {
}
我会保留class LongNastyClass extends Blah[LongNastyClass]
(F边界多态性(。
但是您可以引入宏注释
import scala.annotation.{StaticAnnotation, compileTimeOnly}
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
@compileTimeOnly("enable macro paradise")
class blahBetter extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro BlahBetterMacro.impl
}
object BlahBetterMacro {
def impl(c: whitebox.Context)(annottees: c.Tree*): c.Tree = {
import c.universe._
annottees match {
case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" :: tail =>
val tparams1 = tparams.map {
case q"$_ type $tpname[..$_] = $_" => tpname
}
val parents1 = parents :+ tq"Blah[$tpname[..$tparams1]]"
q"""
$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents1 { $self => ..$stats }
..$tail
"""
}
}
}
@blahBetter
class LongNastyClass
//Warning:scalac: {
// class LongNastyClass extends scala.AnyRef with Blah[LongNastyClass] {
// def <init>() = {
// super.<init>();
// ()
// }
// };
// ()
//}
this.type
不是LongNastyClass
.