与scala反射库不一致

2024-03-01

我无法理解为什么在 2.11.1 中使用 scala 的运行时反射会给出看似不一致的结果。

我正在尝试检查 java 对象中包含的字段的类型,如下所示:

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

public class Example {
  private List<Integer> listOfInts;

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

现在假设我有一个 scala 程序,它尝试推理“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。如果我将类型运算符从<:< to =:=,第一个调用返回 true,第二个调用返回 false。

我在较大的代码体中有一个类似的函数,并且发现即使该函数是静态对象的一部分,也会发生这种行为。使用非参数化类时不会发生这种情况。虽然我希望函数是纯粹的,但事实显然并非如此。进一步的实验表明,某个地方保存着一些持久状态。如果我更换isListType函数与直线代码,我得到这个:

...
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

但如果我在之后重新分配给字段类型<:<运营商,我得到这个:

// 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

在重新分配给字段类型之前<:<运算符给出:

// 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

有谁明白我在这里做错了什么,或者至少有办法解决这个问题?


反射库是基于编译器的,这是一个令人痛心的耻辱。人们应该要求更好。无论如何,事情就是这样。

这是大约两年前的样本票。https://issues.scala-lang.org/browse/SI-6826 https://issues.scala-lang.org/browse/SI-6826

某处保存着一些持久状态

几乎什么都没有。

附录:要获得真正令人眼花缭乱的体验,请逐页浏览 355 个精选内容开放反思 https://issues.scala-lang.org/issues/?jql=status%20%3D%20Open%20AND%20text%20~%20reflection%20ORDER%20BY%20key%20DESC门票。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

与scala反射库不一致 的相关文章

随机推荐

  • 使用 javascript 测试多屏幕

    是否可以判断网站的用户是否使用多个显示器 我需要找到弹出窗口的位置 但用户很可能有多个显示器设置 同时window screenX等将给出浏览器窗口的位置 这对于多个显示器来说是无用的 我在 StackOverflow 上的任何地方都没有找
  • 如何在 iPhone 上记录 SQLite 查询

    我正在开发一个 iPhone 应用程序 并且使用 SQLite 问题是我的查询有一些问题 我做了错误的绑定 所以 这是我的问题 如何使用 SQLite 接收的绑定在我的 iPhone 应用程序中登录有效的 SQL 查询 语句 Thanks
  • 2 个以上线程写入/读取变量的真正危险

    同时读 写单个变量的真正危险是什么 如果我使用一个线程写入一个变量 另一个线程在 while 循环中读取该变量 并且在写入变量时读取该变量并且使用旧值 则不会有危险 这里还有什么危险 同时读 写是否会导致线程崩溃 或者当发生精确的同时读 写
  • 在asp.net core中模拟用户

    我有来自常规 mvc 应用程序的以下代码 它通过模拟用户上传文件 public class PublicController Controller public const int LOGON32 LOGON INTERACTIVE 2 p
  • C++ 映射中的 C 样式数组

    注意 这个问题仅涉及 C 中的映射和数组 碰巧我正在使用 OpenGL 所以那些没有 OpenGL 知识的人不应该阻止进一步阅读 我正在尝试将 C 样式数组放入 C 中std map供以后设置颜色时使用 const map
  • 从 Gorm 模型创建主键时出现问题

    从 Gorm 模型创建主键时 它返回错误 重复列名 id 我的模型看起来像 type User struct gorm Model Id string gorm primary key FirstName string LastName s
  • 在 PHP 闭包中注入代码

    我有一个已经定义的闭包 我想在执行它时在其中注入代码 这是一个例子 predefined print my predefined injected code br closure function print hello br call u
  • 有效证书上的 axios 证书已过期[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 编辑 这是由于https letsencrypt org docs dst root ca x3 expiration septe
  • 流星从复选框 switchChange 中检索 true/false 值

    我有一个附加到复选框的事件处理程序 我正在使用引导开关http www bootstrap switch org http www bootstrap switch org 我试图将 true 或 false 的状态值获取到变量中 以便我可
  • Windows 或 ASP.NET 服务中的 System.Drawing

    根据MSDN http msdn microsoft com en us library system drawing aspx 在 中使用类并不是一个特别好的主意系统图Windows 服务或 ASP NET 服务中的命名空间 现在我正在开
  • 将证书从智能卡复制到计算机

    是否可以将证书从智能卡复制到计算机并 用它来登录某个站点 在 Mac 上 这些证书出现在钥匙串中 并且可以保存到磁盘 但我不确定如何强制站点提示对话框屏幕以选择证书 连接智能卡后 会出现提示并要求选择证书 智能卡包含由封装在 X509 证书
  • 隐藏重复行 SSRS 2008 R2

    我的报告中出现重复的数据 因为源表有重复的数据 在不创建组的情况下 我想隐藏重复的数据写入表达式 所以我做了什么 我选择表行并为表行的隐藏属性添加一个表达式 表情就像是 上一个 字段 ID 值 字段 ID 值 但它不起作用 仍然显示重复的数
  • 选择组中第 i 个 jQuery 对象比 $($(".someclass")[i])) 更简单的方法?

    所以我试图循环遍历 someclass 的成员 不是 DOM 元素 而是它们的 jQuery 对应元素 我一直在使用 someclass i 但这非常丑陋 有更自然的方法来做到这一点吗 你可以使用eq http api jquery com
  • 动态控件组和复选框无样式

    所以我尝试将动态内容直接加载到我的复选框容器 group checkboxes 中 div div 这是我正在运行的用于填充容器的语句 group checkboxes append fieldset fieldset
  • 使重叠内容的容器适合最大孩子的高度

    我正在构建一个在 3 个引号之间旋转的轮播 幻灯片类型小部件 假设标记如下所示 div class carousel blockquote blockquote blockquote blockquote blockquote blockq
  • Laravel 中的“请提供有效的缓存路径”错误

    我复制了一个正在运行的 Laravel 应用程序并将其重命名以用于另一个应用程序 我删除了供应商文件夹并再次运行以下命令 composer self update composer update npm install bower inst
  • 表格页脚自动跨过表格宽度

    我有一张桌子 里面有动态列数取决于我收到的数据 我有一个标签需要分布在所有列上 与表中的列数无关 table thead tr th span ColA span th th span ColB span th th span Col br
  • 为什么gcc中malloc将值初始化为0?

    可能各个平台的情况不一样 但是 当我使用 gcc 编译并运行下面的代码时 我在 ubuntu 11 10 中每次都得到 0 include
  • Microsoft.FSharp.Math.Matrix 发生了什么?

    有点奇怪 这个类类型如何从 VS2010 发布的 F 中删除 有谁知道它去哪儿了 或者现在在哪里 它位于 F powerpack 中 F 团队将其用于 不稳定 代码 这些代码的发布和更新频率将高于 F 和库的主要版本 请注意 该代码仍然是高
  • 与scala反射库不一致

    我无法理解为什么在 2 11 1 中使用 scala 的运行时反射会给出看似不一致的结果 我正在尝试检查 java 对象中包含的字段的类型 如下所示 import java util List import java util ArrayL