标签: scala-reflect

Scala反射中的Dealiasing类型

如何解决给定的别名Type?即

import reflect.runtime.universe._

type Alias[A] = Option[Option[A]]
val tpe = typeOf[Alias[_]] 
val ExistentialType(quantified, underlying) = tpe
Run Code Online (Sandbox Code Playgroud)

我如何Option[Option[_$1]]underlying(或从tpe)获得?我知道这typeSymbol确实解决了别名,但它似乎丢失了过程中的参数:

scala> val tT = typeOf[Alias[_]].typeSymbol
tT: reflect.runtime.universe.Symbol = class Option

scala> tT.asType.toType
res3: reflect.runtime.universe.Type = Option[A]

scala> tT.asType.typeParams
res4: List[reflect.runtime.universe.Symbol] = List(type A)
Run Code Online (Sandbox Code Playgroud)

reflection scala scala-reflect

2
推荐指数
1
解决办法
174
查看次数

Scala反射API Type.dealias有什么作用?

我有一个简单的代码,

case class Person(name: String, age:Int)
import scala.reflect.runtime.universe._
val t1 = typeOf[Person]
val t2 = t1.dealias
println(t1 == t2)
Run Code Online (Sandbox Code Playgroud)

它输出为true,所以我想问一下Type.dealias的用途是什么?我什么时候应该使用它?一些代码示例会有所帮助

我之所以这样问,是因为当我阅读spark代码时ScalaReflection,它几乎总是dealias在使用类型之前使用

scala scala-reflect

2
推荐指数
1
解决办法
120
查看次数

在 Scala 2 或 3 中,是否可以在运行时调试隐式解析过程?

在 scala 语言中,隐式解析通常在编译时完成,有时会抛出混淆的错误信息,此类错误的一个著名例子是当 shapeless Generic 抛出错误信息时,如:

error: could not find implicit value for parameter encoder: CsvEncoder[Foo]
Run Code Online (Sandbox Code Playgroud)

(详见https://books.underscore.io/shapeless-guide/shapeless-guide.html

这个问题的一个解决方案是在运行时运行隐式解析算法(内部应该是图查询算法),这至少有两个好处:

  • 调试工具可用于逐步重现解决过程,因此即使错误信息和文档不完整,也很容易发现错误。

  • 在许多情况下,类型信息可能无法在编译时确定(例如,类型取决于控制流)。如果隐式转换不能延迟到运行时阶段,那么定义隐式转换的许多好处将无效。

所以我的问题是,Scala 2.x 或 Dotty 中是否存在此功能?还是在路线图上?

非常感谢您的意见。

scala implicit dotty scala-reflect scalameta

2
推荐指数
1
解决办法
521
查看次数

动态加载一个Actor,如果它在那里

我有以下代码

lazy val restEndpoint = context.actorOf(Props[RestEndpoint], "RestEndpoint")
Run Code Online (Sandbox Code Playgroud)

但是,我想动态加载actor,如果它存在的原因有以下几点:

  1. 它可能不在类路径上,所以我不得不问类加载器它是否在那里.
  2. 即使它在类路径上,我也可能不想因配置原​​因而加载它.
  3. RestEndpoint位于不同的JAR文件中,该文件已经依赖于此JAR文件,因此我不能拥有循环依赖项.

是否有一些'简单'的方式来反思这样做?请不要指出Scala中有关反射的文档,因为那里没有什么容易的.如果有Scala Reflection for Dummies讨论,我会很感激.

一个工作的例子将不胜感激.

scala akka scala-reflect

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

在运行时从scala中的case类对象中检索fieldname和value

示例案例类:尝试创建通用查询构建器

case class BaseQuery(operand: String, value: String)
case class ContactQuery(phone: BaseQuery, address: BaseQuery)
case class UserQuery(id: BaseQuery, name: BaseQuery, contact: ContactQuery)

val user = UserQuery(BaseQuery("equal","1"), BaseQuery("like","Foo"), ContactQuery(BaseQuery("eq","007-0000"),BaseQuery("like", "Foo City")))


//case class Contact(phone: String, address: String)

//case class User(id: Long, name: String, contact: Contact)

//val user = User(1, "Foo Dev", Contact("007-0000","Foo City"))
Run Code Online (Sandbox Code Playgroud)

我们如何在scala中检索字段名称和相应的值,

在进一步研究中,

使用Scala反射的解决方案:

def classAccessors[T: TypeTag]: List[MethodSymbol] = typeOf[T].members.collect {
    case m: MethodSymbol if m.isCaseAccessor => m
}.toList

// The above snippet returns the field names, and as input …
Run Code Online (Sandbox Code Playgroud)

scala scala-reflect

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

Spark/scala使用特征中的泛型创建空数据集

我有一个称为带有类型参数的特征,其中一个方法需要能够创建一个空的类型化数据集.

trait MyTrait[T] {
    val sparkSession: SparkSession
    val spark = sparkSession.session
    val sparkContext = spark.sparkContext

    def createEmptyDataset(): Dataset[T] = {
        import spark.implicits._ // to access .toDS() function
        // DOESN'T WORK.
        val emptyRDD = sparkContext.parallelize(Seq[T]())
        val accumulator = emptyRDD.toDS()
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我还没有开始工作.它抱怨no ClassTag for T,那value toDS is not a member of org.apache.spark.rdd.RDD[T]

任何帮助,将不胜感激.谢谢!

scala apache-spark scala-reflect

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

使用 Scala 反射从对象获取原始字段的类型

所以我试图获取 Scala 对象类中每个字段的类型:

package myapp.model

object MyObject {
  val theInt: Option[Int]
}
Run Code Online (Sandbox Code Playgroud)

使用 Brian 在这篇文章中慷慨提供的 ReflectionHelper 。我使用getFieldType但它返回Option[Object]而不是它是什么,即Option[Int]. 该答案中的示例代码适用于案例类,例如:

package myapp.model

case class Person(
 name: String,
 age: Option[Int]
)

scala> ReflectionHelper.getFieldType("myapp.model.Person", "age")  // int
res12: Option[reflect.runtime.universe.Type] = Some(Option[Int])
Run Code Online (Sandbox Code Playgroud)

但是,如果我getFieldType在 Scala 对象字段上运行,我们会得到以下结果:

scala> ReflectionHelper.getFieldType("myapp.model.MyObject$", "theInt")
res10: Option[reflect.runtime.universe.Type] = Some(Option[Object])
Run Code Online (Sandbox Code Playgroud)

Scala 对象有什么不同会导致这种行为?我怎样才能getFieldType返回Option[Int]而不是像Option[Object]案例类那样返回?

为了方便起见,这是另一个问题中的 ReflectionHelper:

import scala.reflect.runtime.{ universe => u }
import scala.reflect.runtime.universe._

object ReflectionHelper {

  val classLoader = …
Run Code Online (Sandbox Code Playgroud)

reflection scala scala-reflect

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

来自类型参数的 WeakTypeOf

我有一个带有函数的简单代码,它获取weakTypeOf case 类并返回其字段,可以预见我们得到2 个项目列表

def getMembers[T: WeakTypeTag] = 
  weakTypeOf[T].members.filterNot(_.isMethod).toList

final case class Person(name: String, age: Int) extends Models

val fields = getMembers[Person]
println(fields.length) // 2
Run Code Online (Sandbox Code Playgroud)

它工作正常

但是,如果我想在创建子对象类时从将 Person 作为类型参数传递的 trait 中获取成员呢?(WeakTypeTag 在构建过程中无法传递给 trait)

trait ModelManager[CCT] {
  def getMembers: List[String] = ???
}

case object PersonManager extends ModelManager[Person] 

val fields = PersonManager.getMembers
println(fields.length)
Run Code Online (Sandbox Code Playgroud)

有没有办法从 CCT 参数中获取 weakTypeOf ?

scala implicit scala-reflect

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

在scala中,Map [_,_]和scala.collection.immutable.Map [_,_]如何具有不同的TypeTag?

他们引用相同的东西,但是当我比较2个类型标签时:

val ttg1 = typeTag[Map[_,_]]
val ttg2 = typeTag[immutable.Map[_,_]]

assert(ttg1.tpe == ttg2.tpe)
Run Code Online (Sandbox Code Playgroud)

我有:

Map[_, _] did not equal scala.collection.immutable.Map[_,_]
ScalaTestFailureLocation: 
Expected :scala.collection.immutable.Map[_,_]
Actual   :Map[_, _]
Run Code Online (Sandbox Code Playgroud)

怎么会用键入的语言发生?我如何使它们相同?

更新:对于列表这更令人困惑:

val ttg1 = typeTag[List[_]]
val ttg2 = typeTag[immutable.List[_]]

assert(ttg1.tpe == ttg2.tpe)

List[_] did not equal List[_]
ScalaTestFailureLocation: 
Expected :List[_]
Actual   :List[_]
Run Code Online (Sandbox Code Playgroud)

他们是完全一样的!然而,反思选择忽视它.

reflection scala scala-reflect

0
推荐指数
1
解决办法
70
查看次数

使用 Scala 反射获取构造函数参数值

在带有 Scala 的代码库中工作,它希望您为某些类定义一种“制作新版本” - 例如,如果您有一个类 x(a :int, b:String, c:double).. . 它会有这样的功能:

class x( a: Integer, b : String, c : Double) extends CanMakeNew
{
    def newValue() = x( a, b, c)
}
Run Code Online (Sandbox Code Playgroud)

我无法控制它 - 但不想每次都实现它。或者,嗯……永远。在 Scala 中有一种方法可以通过反射来迭代构造函数参数值吗?我可以使用反射来查看参数类型- 但由于该模块的参数名称尚未打开,我无法打开它 - 我无法将这些与类中存储的值相关联。从根本上说,我正在寻找实现以下特征的方法:

trait CanMakeNewDoneForMe extends CanMakeNew {
    def newValue()  {I need the code that goes here}
Run Code Online (Sandbox Code Playgroud)

那么scala反射有没有办法检查构造函数或检查对象并看到“啊,这是构造函数中的第三个参数”?

reflection scala scala-macros scala-reflect

0
推荐指数
1
解决办法
477
查看次数

为什么 Scala 运行时反射不再适用于 lambda?

下面简单的代码:

import org.scalatest.FunSpec

class RuntimeMirrorSpike extends FunSpec {

  import org.apache.spark.sql.catalyst.ScalaReflection.universe._

  it("can reflect lambda") {

    val ll = { v: String =>
      v.toInt
    }

    val clazz = ll.getClass
    val mirror = runtimeMirror(clazz.getClassLoader)

    val sym = mirror.classSymbol(clazz)

    print(sym)
  }
}

Run Code Online (Sandbox Code Playgroud)

曾经在 Scala 2.11 上完美运行。但现在它在 Scala 2.12 上崩溃了:

assertion failed: no symbol could be loaded from class <...>.spike.RuntimeMirrorSpike$$Lambda$124/78204644 in package spike with name RuntimeMirrorSpike$$Lambda$124/78204644 and classloader sun.misc.Launcher$AppClassLoader@18b4aac2
java.lang.AssertionError: assertion failed: no symbol could be loaded from class <...>.spike.RuntimeMirrorSpike$$Lambda$124/78204644 in package spike with name …
Run Code Online (Sandbox Code Playgroud)

scala scala-reflect scala-2.12

0
推荐指数
1
解决办法
609
查看次数

如何确定一个类是否是父类或特征的子类?

在 Scala 中,我们如何确定一个类是父类的子类还是特征?例如:

trait MyTrait
class MyParentClass()
class MyOtherParentClass()

case class MySubClass() extends MyParentClass with MyTrait
case class MyOtherSubClass() extends MyOtherParentClass
Run Code Online (Sandbox Code Playgroud)

是否可以通过反射 API来确定类是否MySubClass从实例化对象扩展MyParentClassMyTrait不实例化?给定一个未知的泛型类型T,如果T扩展特定的父类或特征,我有兴趣让它匹配一个案例:

def example[T](): Unit = {
    T match {
      case if T extends MyParentClass => ...
      case if T extends MyOtherParentClass => ...
      case if T extends MyOtherTrait => ...
      case _ => default case ...
}
Run Code Online (Sandbox Code Playgroud)

generics reflection scala scala-reflect

0
推荐指数
1
解决办法
175
查看次数