【问题标题】:The difference between running a scala script directly vs through a scala shell直接运行 scala 脚本与通过 scala shell 之间的区别
【发布时间】:2017-03-30 06:38:02
【问题描述】:

我在运行一个简单的脚本时遇到了“No TypeTag available for”错误:

import scala.reflect.runtime.{universe => ru} 
case class Person(name: String)
val classPerson = ru.typeOf[Person].typeSymbol.asClass

该脚本是来自Scala Reflection Doc 的示例。根据this 的帖子,该错误是由于未在顶层定义案例类而导致的。我知道 scala 在运行之前会自动将 scala 脚本编译成一个类,从而使案例类成为内部定义的类,但是如果它在 scala shell 中运行,相同的脚本也可以工作。那么运行 scala 脚本和通过 scala shell 运行相同的脚本有什么区别呢?

【问题讨论】:

    标签: scala reflection


    【解决方案1】:

    在这种情况下,我不确定 Scala Shell 和 Scala 程序之间是否存在差异。如果 case 类没有在 shell 中定义为“顶级”,它仍然无法工作:

    scala> import scala.reflect.runtime.{universe => ru} 
    import scala.reflect.runtime.{universe=>ru}
    
    scala> case class Something(name: String)
    defined class Something
    
    scala> ru.typeOf[Something].typeSymbol.asClass
    res1: reflect.runtime.universe.ClassSymbol = class Something
    
    scala> { case class Something(name: String); ru.typeOf[Something].typeSymbol.asClass }
    
    <console>:16: error: No TypeTag available for Something
        { case class Something(name: String); ru.typeOf[Something].typeSymbol.asClass }
                                                      ^
    

    [编辑] 对下面附加的 cmets 的回应:

    只要案例类被定义为“顶级”,它也可以在程序中工作。以下代码将编译并输出类名:

    import scala.reflect.runtime.{universe => ru} 
    
    case class Something(name: String)
    
    object MyReflection extends App {
      println ("My case class: " + ru.typeOf[Something].typeSymbol.asClass)
    }
    

    【讨论】:

    • 为了澄清我的问题,为什么定义 case class Something(name: String) 而不将它们包含在 {} 中会在 scala shell 中工作,但相同的代码在 scala 脚本中不起作用?跨度>
    • 请在扩展答案中查看我的回复。
    • 感谢您的回复。但是你写了一个 scala 程序,而不是一个 scala 脚本。我明白为什么这个程序会起作用,但我不明白为什么主问题中显示的三行脚本不起作用。
    • 啊,我的错,我以为你在比较 shell 和程序之间的行为。我没有太多使用 Scala 脚本,但我希望 Scala 解释器会将 case 类包装在 wrapper class 中,使其不再是顶级 - 如果您尝试运行 scalac-Ydebug @987654325 就会发现这一点@ 脚本文件的选项,你应该看到类似No TypeTag available for $anon.this.Something
    • 我将三个班轮复制到一个名为 test.scala 的文件中,然后运行 ​​scalac -Ydebug -Xscript test.scala test.scala 并能够复制您的结果。所以这表明,当运行脚本时,脚本中定义的类被包装在另一个包装类中(在这种情况下为$anon) - 但是当通过 scala shell 运行相同的脚本时,这些类每个都被编译为一个顶级班。你认为这是怎么回事?
    猜你喜欢
    • 1970-01-01
    • 2016-10-16
    • 2017-03-09
    • 2012-07-27
    • 2021-03-20
    • 1970-01-01
    • 2013-06-16
    • 2020-01-01
    • 2018-08-22
    相关资源
    最近更新 更多