标签: scala-reflect

获取密封特征的子类

是否有可能(通过宏,某种形式的无形自动或其他形式)获得密封特征的子类列表:

  • 在编译时?
  • 在运行时?

scala shapeless scala-macros scala-reflect

14
推荐指数
1
解决办法
4459
查看次数

构造高等级类型的TypeTag

给出一个简单的参数化类型class LK[A],我可以写

// or simpler def tagLK[A: TypeTag] = typeTag[LK[A]]
def tagLK[A](implicit tA: TypeTag[A]) = typeTag[LK[A]]

tagLK[Int] == typeTag[LK[Int]] // true
Run Code Online (Sandbox Code Playgroud)

现在我想写一个类似的class HK[F[_], A]:

def tagHK[F[_], A](implicit ???) = typeTag[HK[F, A]] 
// or some other implementation?

tagHK[Option, Int] == typeTag[HK[Option, Int]]
Run Code Online (Sandbox Code Playgroud)

这可能吗?我试过了

def tagHK[F[_], A](implicit tF: TypeTag[F[_]], tA: TypeTag[A]) = typeTag[HK[F, A]]

def tagHK[F[_], A](implicit tF: TypeTag[F], tA: TypeTag[A]) = typeTag[HK[F, A]]
Run Code Online (Sandbox Code Playgroud)

但是由于显而易见的原因(在第一种情况下F[_]是存在类型而不是更高级的类型,在第二种TypeTag[F]情况下不能编译),它们都不起作用.

我怀疑答案是"这是不可能的",但如果不是,那将非常高兴.

编辑:我们目前使用WeakTypeTag如下(略微简化):

trait Element[A] {
  val tag: …
Run Code Online (Sandbox Code Playgroud)

scala higher-kinded-types scala-reflect

10
推荐指数
1
解决办法
300
查看次数

Scala:反射和案例类

以下代码成功,但是有更好的方法做同样的事情吗?也许是案例类特有的东西?在下面的代码中,对于我的简单案例类中String类型的每个字段,代码遍历我的案例类的实例列表,并查找该字段的最长字符串的长度.

case class CrmContractorRow(
                             id: Long,
                             bankCharges: String,
                             overTime: String,
                             name$id: Long,
                             mgmtFee: String,
                             contractDetails$id: Long,
                             email: String,
                             copyOfVisa: String)

object Go {
  def main(args: Array[String]) {
    val a = CrmContractorRow(1,"1","1",4444,"1",1,"1","1")
    val b = CrmContractorRow(22,"22","22",22,"55555",22,"nine long","22")
    val c = CrmContractorRow(333,"333","333",333,"333",333,"333","333")
    val rows = List(a,b,c)

    c.getClass.getDeclaredFields.filter(p => p.getType == classOf[String]).foreach{f =>
      f.setAccessible(true)
      println(f.getName + ": " + rows.map(row => f.get(row).asInstanceOf[String]).maxBy(_.length))
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

bankCharges: 3
overTime: 3
mgmtFee: 5
email: 9
copyOfVisa: 3
Run Code Online (Sandbox Code Playgroud)

reflection scala case-class shapeless scala-reflect

8
推荐指数
1
解决办法
932
查看次数

在Scala Reflection中,如何获取具体子类的泛型类型参数?

假设我有一个Generic超类:

class GenericExample[T](
                         a: String,
                         b: T
                       ) {

  def fn(i: T): T = b
}
Run Code Online (Sandbox Code Playgroud)

和一个具体的子类:

case class Example(
                    a: String,
                    b: Int
                  ) extends GenericExample[Int](a, b)
Run Code Online (Sandbox Code Playgroud)

我想通过scala反射得到函数"fn"的类型参数,所以我选择并过滤其成员:

import ScalaReflection.universe._

val baseType = typeTag[Example]

val member = baseType
  .tpe
  .member(methodName: TermName)
  .asTerm
  .alternatives
  .map(_.asMethod)
  .head

    val paramss = member.paramss
    val actualTypess: List[List[Type]] = paramss.map {
      params =>
        params.map {
          param =>
            param.typeSignature
        }
    }
Run Code Online (Sandbox Code Playgroud)

我期待scala给我正确的结果List(List(Int)),相反,我只得到了通用List(List(T))

通过文档进行处理我发现typeSignature是罪魁祸首:

 *  This method always returns signatures in the most generic …
Run Code Online (Sandbox Code Playgroud)

generics scala type-erasure scala-reflect

8
推荐指数
2
解决办法
4862
查看次数

Scala - TypeTags,ClassTags和WeakTypeTags的运行时性能

简介:

... TypeTag[T]封装某些编译时类型的运行时类型表示T....
... TypeTags的总是由编译器生成....... [1]

TypeTags位于scala.reflect.**包装中.另一个SO回答提到使用java反射会在应用程序中产生运行时性能开销.

问题:s,s和s在运行时使用java反射的
程度如何?它们是在编译时生成的,但它们在使用时是否会导致运行时性能开销?TypeTagClassTagWeakTypeTag

示例:

def isOfType[A : ClassTag : TypeTag, E : ClassTag : TypeTag](actual: A, expected: E): Boolean = {
  actual match {
    case _ : E if typeOf[A] =:= typeOf[E] => true
    case _ => false
  }
}

assert( isOfType(List.empty[Int], List.empty[Int]))
assert(!isOfType(List.empty[String], List.empty[Int]))
Run Code Online (Sandbox Code Playgroud)

虽然标签是在编译时生成的,但我可以在运行时感受到延迟.类型比较是否使用了引擎盖下不那么高效的java反射?

reflection scala scala-reflect

7
推荐指数
1
解决办法
1253
查看次数

如何获取传递给 Scala 宏的参数的运行时值?

我有一个表面上很简单的宏观问题,我已经用头撞了几个小时,但没有运气。也许有更多经验的人可以提供帮助。

我有以下宏:

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

object MacroObject {
  def run(s: String): Unit =
    macro runImpl

  def runImpl(c: Context)(s: c.Tree): c.Tree = {
    import c.universe._
    println(s)    // <-- I need the macro to know the value of s at compile time
    q"()"
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是:我希望宏知道s传递给它的值——不是 AST s,而是s它本身的值。具体来说,我希望它具有这种行为:

def runTheMacro(str: String): Unit = MacroObject.run(str)

final val HardCodedString1 = "Hello, world!"
runTheMacro(HardCodedString1)    // the macro should print "Hello, world!"
                                 // to the console during macro expansion …
Run Code Online (Sandbox Code Playgroud)

macros scala scala-macros scala-quasiquotes scala-reflect

6
推荐指数
1
解决办法
528
查看次数

在 Scala 中,如何从可序列化的类型创建 TypeTag?

在 Scala 反射中,通常可以使用 TypeCreator 从 Type 构造 TypeTag:

object TypeUtils {

  import ScalaReflection.universe._

  def createTypeTag[T](
      tpe: Type,
      mirror: reflect.api.Mirror[reflect.runtime.universe.type]
  ): TypeTag[T] = {
    TypeTag.apply(
      mirror,
      NaiveTypeCreator(tpe)
    )
  }

  case class NaiveTypeCreator(tpe: Type) extends reflect.api.TypeCreator {

    def apply[U <: reflect.api.Universe with Singleton](
        m: reflect.api.Mirror[U]): U#Type = {
      //          assert(m eq mirror, s"TypeTag[$tpe] defined in $mirror cannot be migrated to $m.")
      tpe.asInstanceOf[U#Type]
    }
  }

Run Code Online (Sandbox Code Playgroud)

不幸的是,事实证明 的输出createTypeTag不可序列化,这与编译时推理创建的 typeTag 不同:

import java.io.{ByteArrayOutputStream, ObjectOutputStream}

import org.apache.spark.sql.catalyst.ScalaReflection
import org.scalatest.FunSpec

class TypeTagFromType extends FunSpec { …
Run Code Online (Sandbox Code Playgroud)

reflection types scala scala-reflect

6
推荐指数
1
解决办法
181
查看次数

为什么我们必须显式指定ClassTag类型类

现在scala已经使用类型类迭代了JVM 类型的擦除修复ClassTag,为什么它是一个选择加入,而不是让编译器总是捕获运行时检查的类型签名.使它具有隐式参数化类型约束将使得classTag[T]无论泛型参数声明如何都可以调用.

编辑:我应该澄清,我并不是说scala应该改变幕后的签名,总是包含在内ClassTag.相反,我的意思是,因为ClassTag显示scala可以捕获运行时类型信息并因此避免类型擦除限制,为什么不能将该捕获隐含为编译器的一部分,以便该信息始终在scala代码中可用?

我怀疑它是向后兼容性,java生态系统兼容性,二进制大小或运行时开销相关,但这些只是猜测.

scala typeclass scala-reflect

5
推荐指数
1
解决办法
796
查看次数

在编译时列出包中的类

我试图在编译时列出包中的所有类。

让我们定义一个具有以下结构的项目:

com.main
   Main.scala
com.package
   Method.scala
com.package.method1
   Method1.scala
com.package.method2
    Method2.scala
Run Code Online (Sandbox Code Playgroud)

在哪里:

方法.scala

abstract class Method(val name: String) {
}
Run Code Online (Sandbox Code Playgroud)

Method1.scala 和 Method2.scala (更改各自的名称)

class Method1 extends Method(name = "Method1") {
}
Run Code Online (Sandbox Code Playgroud)

我想从 Main.scala 获取 com.package._ 中定义的类列表,如下所示:

object Main() {
    val names = List("Method1", "Method2")
}
Run Code Online (Sandbox Code Playgroud)

我可以对名称进行硬编码(如图所示),但我想知道是否可以在编译时获取这些名称。我知道在运行时可以使用http://software.clapper.org/classutil/

jvm scala scala-macros scala-reflect

5
推荐指数
0
解决办法
269
查看次数

运行时动态编译多个Scala类

我知道我可以使用工具箱在 Scala 中编译单个“片段”,如下所示:

import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox

object Compiler {
  val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()

  def main(args: Array[String]): Unit = {
    tb.eval(tb.parse("""println("hello!")"""))
  }
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以编译不仅仅是“片段”,即相互引用的类?像这样:

import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox

object Compiler {
  private val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()

  val a: String =
    """
      |package pkg {
      |
      |class A {
      |def compute(): Int = 42
      |}}
    """.stripMargin

  val b: String =
    """
      |import pkg._
      |
      |class B {
      |def fun(): Unit = {
      |    new A().compute()
      |}
      |}
    """.stripMargin

  def main(args: Array[String]): …
Run Code Online (Sandbox Code Playgroud)

java reflection scala runtime scala-reflect

5
推荐指数
1
解决办法
491
查看次数