Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala “什么会导致?”;genLoad中出现意外的树“;在宏观扩张中?_Scala_Scala Macros - Fatal编程技术网

Scala “什么会导致?”;genLoad中出现意外的树“;在宏观扩张中?

Scala “什么会导致?”;genLoad中出现意外的树“;在宏观扩张中?,scala,scala-macros,Scala,Scala Macros,我试图生成一个小宏来隔离我遇到的另一个问题,并开始遇到这个编译时错误 Error:scalac: Unexpected tree in genLoad: test.MacroTest$Baz.type/class scala.reflect.internal.Trees$TypeTree at: source-/Users/jpatterson/test/src/test/scala/test/MacroTest.scala,line-5,offset=114 while com

我试图生成一个小宏来隔离我遇到的另一个问题,并开始遇到这个编译时错误

Error:scalac: 
  Unexpected tree in genLoad: test.MacroTest$Baz.type/class scala.reflect.internal.Trees$TypeTree at: source-/Users/jpatterson/test/src/test/scala/test/MacroTest.scala,line-5,offset=114
     while compiling: /Users/jpatterson/test/src/test/scala/test/MacroTest.scala
        during phase: jvm
     library version: version 2.13.0-RC1
    compiler version: version 2.13.0-RC1
  reconstructed args: -deprecation -Vimplicits -language:higherKinds -language:implicitConversions -language:postfixOps -classpath ... (cut)
last tree to typer: Literal(Constant(test.MacroTest.MacroTest$Baz.type))
       tree position: line 4 of /Users/jpatterson/test/src/test/scala/test/MacroTest.scala
            tree tpe: Class(classOf[test.MacroTest$Baz$])
              symbol: null
           call site: constructor MacroTest$$anon$1 in package test
== Source file context for tree position ==
     1 package test
     2 
     3 object MacroTest {
     4   case class Baz(x: Int, y: Int)
     5   implicit def bazRead: Read[Baz] = Read.readFor[Baz]
     6 
     7   def main(args: Array[String]): Unit = {
我开始使用scala 2.12.8。我试着切换到2.13.0-RC1,只是想看看它是否已经被修复了。这两个版本的scala都失败了

宏代码:

package test

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

trait Read[A] {
  def read(in: String): A
}

object Read {
  implicit def intRead = new Read[Int] {
    override def read(in: String): Int = in.toInt
  }

  def CaseClassReadImpl[A: c.WeakTypeTag](c: Context): c.Expr[Read[A]] = {
    import c.universe._
    val aType = weakTypeOf[A]

    val params = aType.decls.collect {
      case m: MethodSymbol if m.isCaseAccessor => m
    }.toList

    val paramList = params.map(param => q"Read.read[${param.typeSignature}](in)")

    val src = q"""
      new Read[$aType] {
        def read(in: String) = ${aType.companion}.apply(..$paramList)
      }
    """

    println(src)
    c.Expr[Read[A]](src)
  }

  def readFor[A]: Read[A] = macro CaseClassReadImpl[A]

  def read[A](in: String)(implicit A: Read[A]): A = A.read(in)
}
执行它的代码:

package test

object MacroTest {
  case class Baz(x: Int, y: Int)
  implicit def bazRead: Read[Baz] = Read.readFor[Baz]

  def main(args: Array[String]): Unit = {
    println(Read.read[Baz]("4"))
  }
}

编译第二个块会导致上述错误


我希望它能正确编译。我将
println
放入宏定义中,这样我就可以获取代码并尝试编译它。当我将其添加到第二个块时,它编译得很好。我甚至可以用它替换
bazRead
的值,一切都按预期工作:它打印出
Baz(4,4)

关于你的宏,试着用
${aType.companion}
替换
${aType.typeSymbol.companion}


对于派生类型类,最好使用或而不是原始宏

例如,在Shapeless
Read
中,可以按如下方式导出

import shapeless.{Generic, HList, HNil, ::}

trait Read[A] {
  def read(in: String): A
}

object Read {
  implicit def intRead: Read[Int] = _.toInt

  implicit def hNilRead: Read[HNil] = _ => HNil

  implicit def hConsRead[H, T <: HList](implicit r: Read[H], r1: Read[T]): Read[H :: T] = 
    in => r.read(in) :: r1.read(in)

  implicit def caseClassRead[A, L <: HList](implicit gen: Generic.Aux[A, L], r: Read[L]): Read[A] = 
    in => gen.from(r.read(in))

  def read[A](in: String)(implicit A: Read[A]): A = A.read(in)
}

case class Baz(x: Int, y: Int)

Read.read[Baz]("123") // Baz(123,123)
导入无形状。{Generic,HList,HNil,:}
阅读[A]{
def read(在:字符串中):A
}
对象读取{
隐式def intRead:Read[Int]=\uu.toInt
隐式def hNilRead:Read[HNil]=\u=>HNil
隐式def hConsRead[H,tr.read(in)::r1.read(in)
隐式def caseClassRead[A,L根自(r根自(in))
def read[A](in:String)(隐式A:read[A]):A=A.read(in)
}
案例类别Baz(x:Int,y:Int)
Read.Read[Baz](“123”)//Baz(123123)

是的,我从来没有花时间去克服这种不成形的学习曲线,但这只是一个小例子,我一起尝试找出我遇到的另一个问题。感谢您的快速回复!