在变量中存储长的准引用匹配项

问题描述

我正在努力避免比赛中重复长的准引用。因此,我想将其转换为:

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,Template(parents,self,body)) =>
    ClassDef(mods,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)
}

在复杂的情况下,您可以使用自定义提取器对象。

如果您经常在类主体中添加树,则可以引入辅助方法

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)
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...