Scala 隐藏了奇怪的递归模板模式



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.

最新更新