加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何将类型编程与Scala宏结合使用

发布时间:2020-12-16 10:02:57 所属栏目:安全 来源:网络整理
导读:我想使用一个使用“type”关键字定义的类型的宏.我该如何参考? 我的起始代码是 import scala.reflect.macros.Contextimport scala.language.experimental.macrostrait Demo6 { type T def add(param: Any): T = macro Demo6.addImpl[T] def fullAdd(param:
我想使用一个使用“type”关键字定义的类型的宏.我该如何参考?

我的起始代码是

import scala.reflect.macros.Context
import scala.language.experimental.macros

trait Demo6 {
  type T

  def add(param: Any): T = macro Demo6.addImpl[T]

  def fullAdd(param: Any,toStringBasedOnAST: String): T = {
    doesSomeThing_and_returnsSomething_OfTypeT
  }
  def doesSomeThing_and_returnsSomething_OfTypeT: T //just to allow compilation
}

object Demo6 {
  def addImpl[T: c.WeakTypeTag](c: Context)(param: c.Expr[Any]): c.Expr[T] = {
    import c.universe._
    reify { (c.Expr[Demo6](c.prefix.tree)).splice.fullAdd(param.splice,c.literal(show(param.tree)).splice) }
    //        ^ - type mismatch; found : org.autotdd.scalamacros.Demo6#T 
    //                           required: T
  }
}

我在示例中标记了编译器错误.很明显发生了什么:关键字定义的类型T与我传入的类型T不同.

我尝试过的事情
scala-macros上还没有很多文档. http://docs.scala-lang.org/overviews/macros/overview.html中的部分非常有助于我这么做,但它的示例使用了类级别和方法级别泛型.我浏览了Expecty和macrocosm的代码,这些是文档中引用的项目,但找不到这样的代码.

解决方法

您的代码几乎是正确的,只需更改Expr的类型参数:

val expr = reify { ... }
c.Expr[T](expr.tree)

没有reify你应该返回:

c.Expr[T](Apply(Select(c.prefix.tree,newTermName("fullAdd")),List(param.tree,Literal(Constant(show(param.tree))))))

reify创建相同但具有错误的类型参数.

有关showRaw的使用,请参阅this answer.

在这种情况下:

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> {
     |   object Demo { def fullAdd(param1: Any,param2: String): String = "result" }
     |   showRaw{ reify { Demo.fullAdd("param1","param2") } }
     | }
res0: String = Expr(Apply(Select(Ident(newTermName("Demo")),List(Literal(Constant("param1")),Literal(Constant("param2")))))

用c.prefix.tree替换Ident(newTermName(“Demo”)),用param.tree替换Literal(常量(“param1”))和用show(param.tree)替换“param2”,你将得到你的结果.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读