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

scala – 使用宏转换树后重新建立类型一致性的最佳方法是什么

发布时间:2020-12-16 18:16:42 所属栏目:安全 来源:网络整理
导读:我有以下宏: def testMacro[T](x: T): Option[T] = macro testMacroImpl[T]def testMacroImpl[T: c.WeakTypeTag](c: Context)(x: c.Expr[T]): c.Expr[Option[T]] = { import c.universe._ val newTree = x.tree match { case Block(List(first),second) = {
我有以下宏:

def testMacro[T](x: T): Option[T] = macro testMacroImpl[T]

def testMacroImpl[T: c.WeakTypeTag](c: Context)(x: c.Expr[T]): c.Expr[Option[T]] = {
    import c.universe._
    val newTree = x.tree match {
      case Block(List(first),second) => {
        val newFirst = first match {
          case ValDef(mods,name,_,rhs) => ValDef(mods,EmptyTree,q"Some($rhs)")
        }
        Block(List(newFirst),second)
      }
    }
    c.Expr[Option[T]](newTree)
  }

基本上,这应该改变这个:

testMacro {
    val aa = "hello"
    aa
}

{
    val aa = Some("hello")
    aa
}

但是,它失败并出现以下错误:

[error]  found   : String
[error]  required: Option[String]
[error]     val f = IdiomBracket.testMacro{
[error]   
                                          ^

我的调查表明,这是因为它接收到一个类型为树的标识符aa的类型树.由于代码转换,它现在是Option [String]类型,但标识符的类型尚未更新.我尝试创建一个新的(无类型)标识符,这只会产生错误:

[error]  found   : <notype>
[error]  required: Option[String]
[error]     val f = IdiomBracket.testMacro{
[error]                                   ^

我已经尝试在发送之前对树进行类型检查,希望这样可以填写正确的类型,但这似乎没有任何效果.

作为参考,这里是创建一个新的Ident并执行类型检查的相同的宏,但遗憾的是它仍然不起作用.

def testMacroImpl[T: c.WeakTypeTag](c: Context)(x: c.Expr[T]): c.Expr[Option[T]] = {
    import c.universe._
    val newTree = x.tree match {
      case Block(List(first),q"Some($rhs)")
        }
        val newSecond = second match {
          case ident: Ident => Ident(ident.name)
        }
        Block(List(newFirst),newSecond)
      }
    }
    c.Expr[Option[T]](c.typecheck(newTree))
  }

解决方法

这一行:

case ValDef(mods,q"Some($rhs)")

需要更改为此行:

case ValDef(mods,TypeTree(),q"Some($rhs)")

将EmptyTree作为ValDef中的类型可能永远不会有意义.太糟糕了,编译器无法告诉我,本来可以节省48小时的兼职工作.

(编辑:李大同)

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

    推荐文章
      热点阅读