scala macro annotation 使用 例子
来源:互联网 发布:农村淘宝订单佣金 编辑:程序博客网 时间:2024/06/03 23:05
功能:用 宏注解实现一个 为case class 生成get set 方法 注解
github 地址:https://github.com/1178615156/use-scala-macro-annotation-make-get-set
//功能如下
@MakeGetSetcase class Hello( var a: String, var int: Int, var option: Option[String], var none: Option[AnyRef] = None, val hello: Boolean = true )object Main { def main(args: Array[String]) { val a = new Hello("a", 1, Some("option")) //a.a println(a.getA)//a //a.int println(a.getInt)//1 //return option.getOrElse(null) println(a.getOption)//option //return option.getOrElse(null) println(a.getNone)//null //a.none=Option(Some("")) a.setNone(Some("")) println(a.none)//Some(Some()) //a.none=Some("") a.none = Some("") println(a.none)//Some() println(a.getHello)//true //no have this method because hello is val //a.setHello(false ) }}
宏 的实现代码 :
import scala.reflect.macros.blackbox.Contextimport scala.language.experimental.macrosimport scala.annotation.{compileTimeOnly, StaticAnnotation}/** * Created by YuJieShui on 2015/9/4. */@compileTimeOnly("")class MakeGetSet extends StaticAnnotation { def macroTransform(annottees: Any*): Any = macro AnnotationGetSetMacroImpl.impl}class AnnotationGetSetMacroImpl(val c: Context) { import c.universe._ //get case class def getInCaseClass(list_annottees: List[Tree]) = list_annottees match { case caseClass :: Nil => caseClass case caseClass :: companionObject :: Nil => caseClass } def impl(annottees: c.Expr[Any]*): c.Expr[Any] = { val inCaseClass = getInCaseClass(annottees.map(_.tree).toList) val out: c.universe.Tree = inCaseClass match { //if inCaseClass no a case class //throw match error case q"case class $name(..$params) extends ..$bases { ..$body }" => val list_params: List[ValDef] = params.asInstanceOf[List[ValDef]] val get_set_params_func = list_params.map((param: c.universe.ValDef) => { //get method name val get_name = TermName("get" + { val vn = param.name.toString; vn.head.toString.toUpperCase() + vn.tail }) //set method name val set_name = TermName("set" + { val vn = param.name.toString; vn.head.toString.toUpperCase() + vn.tail }) param match { case ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) => val v_type: c.universe.Tree = tq"$tpt" //如果参数类型为泛型参数 v_type.children.headOption.map { // where type is Option[_] case tq"Option" => Tuple2( q"""@..${mods.annotations} def $get_name = $name.orNull """, //where value is var //make set method if (mods.hasFlag(Flag.MUTABLE)) q"def $set_name(sss:${v_type.children(1)}):Unit=this.${name}=Option(sss)" else q"" ) //other such : Future[_],List[_] case _ => Tuple2( q"def $get_name = ${param.name}", q"" ) } //非泛型参数 .getOrElse(Tuple2( q"def $get_name= {${param.name}}", if (mods.hasFlag(Flag.MUTABLE)) q"def $set_name(sss:$v_type):Unit=this.${name}=sss" else q"" )) } }).flatMap(t2 => List(t2._1, t2._2)) q""" case class $name(..$params) extends ..$bases { ..$get_set_params_func ..$body } """ } c.Expr(out) }}
0 0
- scala macro annotation 使用 例子
- java Annotation使用例子
- scala slick 使用macro 实现根据字段名排序
- Scala中的Map使用例子
- Scala中json4s的使用例子
- 使用scala隐式转换的例子
- Scala Annotation (注解)
- 使用 vs2008 宏 Macro
- iOS Macro的使用
- Hibernate4使用Annotation连接访问MySQL的小例子
- Hibernate4使用Annotation连接访问MySQL的小例子
- macro
- macro
- macro
- Hibernate annotation 例子
- 自定义Annotation入门例子
- Annotation的简单例子
- java annotation 例子
- javaSE基础编程——编写一个简单的计算器
- Android下得到APK包含信息
- sentinel运维监控
- UVa 10954 Add All (石子合并_优先队列)
- org.springframework.dao.InvalidDataAccessApiUsageException: Name must not be null or empty!;
- scala macro annotation 使用 例子
- hdoj 1042 N! 【大数阶乘】
- Linux下推荐应用程序列表【2008-07-31】
- CCF 201312-4 有趣的数 (数位DP)
- 一张图看懂 why 代理和数据源 使用 weak 修饰
- 【HDU1507】【最大匹配输出路径match数组】
- 文章标题
- Jquery ui Interactions方法的使用实例
- Kinect v2.0原理介绍之七:彩色帧获取