在变量中存储长准引用匹配器
Storing long quasiquote matchers in a variable
我正在努力避免在匹配中重复使用长的准引号。所以,我想将其转换为:
def appendTree(clazz: ClassDef, tree: Tree): ClassDef =
clazz match {
case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats; ..$tree }"
}
像这样:
val clazzQuote = "$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }"
def appendTree(clazz: ClassDef, tree: Tree): ClassDef =
clazz match {
case q"$clazzQuote" =>
q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats; ..$tree }"
}
我尝试使用字符串插值进行比较的示例:
val msg = "hello $name"
"hello world" match {
case s"$msg" => println(name) // I want this to output "world"
}
这个例子doesn't work也可以。
我该怎么做? (或者我可以吗?)
你不会写
val msg = s"hello $name" // name doesn't make sense here
或
val clazzQuote = "$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }"
// mods, tpname, tparams, ... do not make sense here
Scala 中的模式匹配不是这样工作的。
你可以这样写
clazz match {
case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats; $tree }"
}
或
clazz match {
case ClassDef(mods, name, tparams, Template(parents, self, body)) =>
ClassDef(mods, name, tparams, Template(parents, self, body :+ tree))
}
或
clazz match {
case c: ClassDef =>
val i = c.impl
ClassDef(c.mods, c.name, c.tparams, Template(i.parents, i.self, i.body :+ tree))
}
如果不需要所有参数可以使用下划线
clazz match {
case q"$_ class $tpname[..$_] $_(...$_) extends $_" =>
println(tpname)
}
或
clazz match {
case q"$_ class $_[..$_] $_(...$_) extends { ..$_ } with ..$parents { $_ => ..$_ }" =>
println(parents)
}
在复杂的情况下,您可以使用自定义提取器对象。
如果经常给classbody添加树可以引入辅助方法
def modifyBody(clazz: ClassDef, f: List[Tree] => List[Tree]): ClassDef =
clazz match {
case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..${f(stats)} }"
}
def appendTree(clazz: ClassDef, tree: Tree): ClassDef = {
clazz match {
case c => modifyBody(c, stats => stats :+ tree)
}
我正在努力避免在匹配中重复使用长的准引号。所以,我想将其转换为:
def appendTree(clazz: ClassDef, tree: Tree): ClassDef =
clazz match {
case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats; ..$tree }"
}
像这样:
val clazzQuote = "$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }"
def appendTree(clazz: ClassDef, tree: Tree): ClassDef =
clazz match {
case q"$clazzQuote" =>
q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats; ..$tree }"
}
我尝试使用字符串插值进行比较的示例:
val msg = "hello $name"
"hello world" match {
case s"$msg" => println(name) // I want this to output "world"
}
这个例子doesn't work也可以。
我该怎么做? (或者我可以吗?)
你不会写
val msg = s"hello $name" // name doesn't make sense here
或
val clazzQuote = "$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }"
// mods, tpname, tparams, ... do not make sense here
Scala 中的模式匹配不是这样工作的。
你可以这样写
clazz match {
case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats; $tree }"
}
或
clazz match {
case ClassDef(mods, name, tparams, Template(parents, self, body)) =>
ClassDef(mods, name, tparams, Template(parents, self, body :+ tree))
}
或
clazz match {
case c: ClassDef =>
val i = c.impl
ClassDef(c.mods, c.name, c.tparams, Template(i.parents, i.self, i.body :+ tree))
}
如果不需要所有参数可以使用下划线
clazz match {
case q"$_ class $tpname[..$_] $_(...$_) extends $_" =>
println(tpname)
}
或
clazz match {
case q"$_ class $_[..$_] $_(...$_) extends { ..$_ } with ..$parents { $_ => ..$_ }" =>
println(parents)
}
在复杂的情况下,您可以使用自定义提取器对象。
如果经常给classbody添加树可以引入辅助方法
def modifyBody(clazz: ClassDef, f: List[Tree] => List[Tree]): ClassDef =
clazz match {
case q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..$stats }" =>
q"$mods class $tpname[..$tparams] $ctorMods(...$paramss) extends { ..$earlydefns } with ..$parents { $self => ..${f(stats)} }"
}
def appendTree(clazz: ClassDef, tree: Tree): ClassDef = {
clazz match {
case c => modifyBody(c, stats => stats :+ tree)
}