Scala解释器有哪些限制和解决方法?

时间:2010-09-08 00:58:17

标签: scala scala-2.8

什么样的构造需要'scalac'编译以及如何创建一个可以在解释器中工作的等价物?

编辑:我想使用scala而不是python作为脚本语言。 (使用#!/ usr / bin / scala)

3 个答案:

答案 0 :(得分:6)

您应该能够在REPL中执行任何可以在外部代码中执行的操作。请记住:

  • 循环引用的东西需要在一个区块内。所以以下内容不能按原样输入;你必须将它包装在其他对象中:

    class C(i : Int) { def succ = C(i+1) }
     object C { def apply(i: Int) = new C(i) }

  • 执行环境有所不同,因此基准测试时间并不总是与从编译代码中运行它们的方式相同。

  • 您以不同的方式输入执行路径;但是,如果你想调用main方法,你当然可以在REPL内部。

  • 您不能将整个库剪切并粘贴到REPL中,并使其工作与库一样; REPL具有与普通包不同的结构。因此,在测试期间删除“包”声明。

答案 1 :(得分:3)

编辑:再次阅读你的问题后,我不得不承认,我没有真正回答它;)。但也许它仍然有帮助。

我知道解释器(或REPL)的两个限制,当涉及到加载scala文件时(为了交互式测试它们)。

  • 您无法加载包含包定义的scala文件。 REPL抱怨并且不加载所有类是要加载的scala文件。它认为它与加载到REPL中的文件被视为对象这一事实有关。 。 。其中当然不能包含任何包装定义。
  • 当类路径中存在加载的scala文件的类文件时,REPL很奇怪(或者有点不可预测)。查看this question by myself,特别是我的第二个回答的最后两条评论。

此外,循环依赖项存在问题,我不知道解决方法:假设有一个使用类A的类B,它还需要A来执行这是工作。当然,您无法定义A,因为没有B的定义,反之亦然。为其中一个提供假人也不起作用:

scala> class A {                                           
 |   def alterString(s:String) = s                     
 |   def printStuff(s:String) = println(alterString(s))
 | }                                                   
defined class A

scala> class B {                                           
 |   val prefix = "this is a test: "                   
 |   def doJob() = new A() printStuff "1 2 3"            
 | }
defined class B

scala> class A {
 |   def alterString(s:String) = new B().prefix + s
 |   def printStuff(s:String) = println(alterString(s))
 | }
defined class A

scala> new B().doJob()
1 2 3

scala> 

虽然我已经提供了A的更新定义,但类B仍然使用了我定义它时存在的那个。

答案 2 :(得分:0)

我认为Scala中的所有内容都可以从解释器中运行(我相信无论如何都只是将编译器称为编译器)。

你怀疑有什么不行吗?或者这是一个技巧/访谈问题(我想任何想要直接与类加载器或类文件交互的东西在这两个环境中的行为可能会有所不同,但我真的不知道。)