如何解决给定的别名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) 我有一个简单的代码,
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 语言中,隐式解析通常在编译时完成,有时会抛出混淆的错误信息,此类错误的一个著名例子是当 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 中是否存在此功能?还是在路线图上?
非常感谢您的意见。
我有以下代码
lazy val restEndpoint = context.actorOf(Props[RestEndpoint], "RestEndpoint")
Run Code Online (Sandbox Code Playgroud)
但是,我想动态加载actor,如果它存在的原因有以下几点:
是否有一些'简单'的方式来反思这样做?请不要指出Scala中有关反射的文档,因为那里没有什么容易的.如果有Scala Reflection for Dummies讨论,我会很感激.
一个工作的例子将不胜感激.
示例案例类:尝试创建通用查询构建器
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) 我有一个称为带有类型参数的特征,其中一个方法需要能够创建一个空的类型化数据集.
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 对象类中每个字段的类型:
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) 我有一个带有函数的简单代码,它获取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 ?
他们引用相同的东西,但是当我比较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)
他们是完全一样的!然而,反思选择忽视它.
在带有 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反射有没有办法检查构造函数或检查对象并看到“啊,这是构造函数中的第三个参数”?
下面简单的代码:
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 中,我们如何确定一个类是父类的子类还是特征?例如:
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从实例化对象扩展MyParentClass或MyTrait不实例化?给定一个未知的泛型类型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) scala ×12
scala-reflect ×12
reflection ×5
implicit ×2
akka ×1
apache-spark ×1
dotty ×1
generics ×1
scala-2.12 ×1
scala-macros ×1
scalameta ×1