编程语言
首页 > 编程语言> > Scala宏编程实战之宏的注解拓展 - 实现toString,builder,constructor,equalsAndHashCode等

Scala宏编程实战之宏的注解拓展 - 实现toString,builder,constructor,equalsAndHashCode等

作者:互联网

项目地址

Intellij IDEA 插件

@toString

@toString注解用于为Scala类生成toString方法。

@toString class TestClass(val i: Int = 0, var j: Int) {
  val y: Int = 0
  var z: String = "hello"
  var x: String = "world"
}

println(new TestClass(1, 2));
includeInternalFields / includeFieldNamesfalsetrue
falseTestClass(1, 2)TestClass(i=0, j=2)
trueTestClass(1, 2, 0, hello, world)TestClass(i=1, j=2, y=0, z=hello, x=world)

@json

@json注解是向Play项目的样例类添加json format对象的最快方法。

@json case class Person(name: String, age: Int)

现在,您可以使用Play的转化方法序列化或反序列化对象:

import play.api.libs.json._

val person = Person("Victor Hugo", 46)
val json = Json.toJson(person)
Json.fromJson[Person](json)

@builder

@builder注解用于为Scala类生成构造器模式。

@builder
case class TestClass1(val i: Int = 0, var j: Int, x: String, o: Option[String] = Some(""))

val ret = TestClass1.builder().i(1).j(0).x("x").build()
assert(ret.toString == "TestClass1(1,0,x,Some())")

宏生成的中间代码:

object TestClass1 extends scala.AnyRef {
  def <init>() = {
    super.<init>();
    ()
  };
  def builder(): TestClass1Builder = new TestClass1Builder();
  class TestClass1Builder extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };
    private var i: Int = 0;
    private var j: Int = _;
    private var x: String = _;
    private var o: Option[String] = Some("");
    def i(i: Int): TestClass1Builder = {
      this.i = i;
      this
    };
    def j(j: Int): TestClass1Builder = {
      this.j = j;
      this
    };
    def x(x: String): TestClass1Builder = {
      this.x = x;
      this
    };
    def o(o: Option[String]): TestClass1Builder = {
      this.o = o;
      this
    };
    def build(): TestClass1 = TestClass1(i, j, x, o)
  }
}

@synchronized

@synchronized注解是一个更方便、更灵活的用于同步方法的注解。


private final val obj = new Object

@synchronized(lockedName = "obj") // 如果您填写一个不存在的字段名,编译将失败。
def getStr3(k: Int): String = {
  k + ""
}

// 或者
@synchronized //使用 this 作为锁对象
def getStr(k: Int): String = {
  k + ""
}

宏生成的中间代码:

// 注意,它不会判断synchronized是否已经存在,因此如果synchronized已经存在,它将被使用两次。如下 
// `def getStr(k: Int): String = this.synchronized(this.synchronized(k.$plus("")))
// 目前还不确定是否在字节码级别会被优化。
def getStr(k: Int): String = this.synchronized(k.$plus(""))

@log

@log注解不使用混入和包装,而是直接使用宏生成默认的log对象来操作log。

@log(verbose = true) class TestClass1(val i: Int = 0, var j: Int) {
  log.info("hello")
}

@log(verbose=true, logType=io.github.dreamylost.LogType.Slf4j) class TestClass6(val i: Int = 0, var j: Int){ log.info("hello world") }

@apply

@apply注解用于为普通类的主构造函数生成apply方法。

@apply @toString class B2(int: Int, val j: Int, var k: Option[String] = None, t: Option[Long] = Some(1L))
println(B2(1, 2, None, None)) //0.1.0,不携带字段的默认值到apply参数中,所以参数都是必传

@constructor

@constructor注解用于为普通类生成辅助构造函数。仅当类有内部字段时可用。

@constructor(excludeFields = Seq("c")) //排除c字段。其中,a是val的不需要手动指定,自动排除。
class A2(int: Int, val j: Int, var k: Option[String] = None, t: Option[Long] = Some(1L)) {
  private val a: Int = 1
  var b: Int = 1 // 不携带字段的默认值到apply参数中,所以参数都是必传
  protected var c: Int = _

  def helloWorld: String = "hello world"
}

println(new A2(1, 2, None, None, 100))

宏生成的中间代码(仅构造函数部分):

def <init>(int: Int, j: Int, k: Option[String], t: Option[Long], b: Int) = {
  <init>(int, j, k, t);
  this.b = b
}

@equalsAndHashCode

@equalsAndHashCode注解用于为普通类生成equalshashCode方法,同时均考虑超类的影响。

@equalsAndHashCode(verbose = true)
class Person(var name: String, var age: Int)

宏生成的中间代码:

class Person extends scala.AnyRef {
  <paramaccessor> var name: String = _;
  <paramaccessor> var age: Int = _;
  def <init>(name: String, age: Int) = {
    super.<init>();
    ()
  };
  def canEqual(that: Any) = that.isInstanceOf[Person];
  override def equals(that: Any): Boolean = that match {
    case (t @ (_: Person)) => t.canEqual(this).$amp$amp(Seq(this.name.equals(t.name), this.age.equals(t.age)).forall(((f) => f))).$amp$amp(true)
    case _ => false
  };
  override def hashCode(): Int = {
    val state = Seq(name, age);
    state.map(((x$2) => x$2.hashCode())).foldLeft(0)(((a, b) => 31.$times(a).$plus(b)))
  }
}

标签:equalsAndHashCode,String,val,Scala,Int,builder,var,class,def
来源: https://blog.csdn.net/qq_34446485/article/details/118939177