与Scala反射库不一致 [英] Inconsistency with scala reflection library

查看:87
本文介绍了与Scala反射库不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解为什么在2.11.1中使用scala的运行时反射会给我看似不一致的结果.

I'm having trouble understanding why using scala's runtime reflection in 2.11.1 gives me seemingly inconsistent results.

我正在尝试检查包含在Java对象中的字段的类型,就像这样:

I am trying to inspect the type of a field contained in a java object, like this one:

import java.util.List;
import java.util.ArrayList;

public class Example {
  private List<Integer> listOfInts;

  public Example () {
    listOfInts = new ArrayList<Integer>();
  }  
}

现在假设我有一个scala程序,该程序试图推断示例:"中字段的类型.

Now suppose I have a scala program that tries to reason about the type of the field inside "Example:"

import java.lang.Class
import java.lang.reflect.Field
import java.util.List
import scala.reflect.runtime.{ universe => ru }

object Inspect extends scala.App {
  val example = new Example 
  val cls = example.getClass
  val listfield = cls.getDeclaredField("listOfInts")

  println(isListType(listfield)) // prints false 
  println(isListType(listfield)) // prints true, as do all subsequent calls

  def isListType (field: Field): Boolean = {
    /*
      A function that returns whether the type of the field is a list.
      Based on examples at http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html
    */
    val fieldcls = field.getType

    val mirror: ru.Mirror = ru.runtimeMirror(getClass.getClassLoader)
    val fieldsym: ru.ClassSymbol = mirror.classSymbol(fieldcls)
    val fieldtype: ru.Type = fieldsym.toType 

    (fieldtype <:< ru.typeOf[List[_]])
  }  
}

在此特定代码段中,第一次调用isListType返回false,第二次返回true.如果我将类型运算符从<:<切换为=:=,则第一个调用返回true,第二个返回false.

In this particular code snippet, the first call to isListType returns false, and the second returns true. If I switch the type operator from <:< to =:=, the first call returns true, and the second false.

我在较大的代码体内有一个类似的功能,并且发现即使该功能是静态对象的一部分,也会发生这种现象.使用未参数化的类时不会发生这种情况.虽然我希望函数是纯函数,但事实并非如此.进一步的实验表明,某处存在某种持久状态.如果用直线代码替换isListType函数,我会得到:

I have a similar function in a larger code body, and have found that even when the function is part of a static object, this behavior occurs. This does not happen when using unparameterized classes. While I intended for the function to be pure, this is obviously not the case. Further experimentation has shown that there is some persistent state held somewhere. If I replace the isListType function with straightline code, I get this:

...
val example = new Example   
val cls = example.getClass
val listfield = cls.getDeclaredField("listOfInts")
val fieldcls = listfield.getType

val mirror: ru.Mirror = ru.runtimeMirror(getClass.getClassLoader)
val fieldsym: ru.ClassSymbol = mirror.classSymbol(fieldcls)
val fieldtype: ru.Type = fieldsym.toType 

println(fieldtype <:< ru.typeOf[List[_]]) // prints false
println(fieldtype <:< ru.typeOf[List[_]]) // prints false

但是如果我在<:<运算符之后重新分配给字段类型,我会得到:

but if I reassign to field type after the <:< operator, I get this:

// replace as under the fieldsym assignment
var fieldtype: ru.Type = fieldsym.toType 
println(fieldtype <:< ru.typeOf[List[_]]) // prints false

fieldtype = fieldsym.toType 
println(fieldtype <:< ru.typeOf[List[_]]) // prints true

<:<运算符给出以下内容之前重新分配为字段类型:

while reassigning to field type before the <:< operator gives this:

// replace as under the fieldsym assignment
var fieldtype: ru.Type = fieldsym.toType 
fieldtype = fieldsym.toType 

println(fieldtype <:< ru.typeOf[List[_]]) // prints false
println(fieldtype <:< ru.typeOf[List[_]]) // prints false

有人知道我在做什么错吗,或者至少有办法解决这个问题?

Does anyone understand what I'm doing wrong here, or at least have a way around this?

推荐答案

反射库基于编译器,这真是令人遗憾.人们应该要求更好.无论如何,这就是事实.

The reflection library is based on the compiler, which is a crying shame. People should demand better. Anyway, this is just how it is.

这是将近两年前的样品票. https://issues.scala-lang.org/browse/SI-6826

Here's a sample ticket from almost two years ago. https://issues.scala-lang.org/browse/SI-6826

某处存在某种持久状态

there is some persistent state held somewhere

几乎什么都没有.

附录:要获得真正令人眼花experience乱的体验,请选择355个

Addendum: for a truly dizzying experience, page through a selection of the 355 open reflection tickets.

这篇关于与Scala反射库不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆