当前位置:  开发笔记 > 编程语言 > 正文

Scala REPL中的递归重载语义--JVM语言

如何解决《ScalaREPL中的递归重载语义--JVM语言》经验,为你挑选了2个好方法。

使用Scala的命令行REPL:

def foo(x: Int): Unit = {}
def foo(x: String): Unit = {println(foo(2))}

error: type mismatch;
found: Int(2)
required: String

看来你无法在REPL中定义重载的递归方法.我认为这是Scala REPL中的一个错误并提交了它,但它几乎立即关闭了"wontfix:我没有看到任何方式这可以支持解释器的语义,因为这两个方法必须编译一起." 他建议将方法放在一个封闭的对象中.

是否有JVM语言实现或Scala专家可以解释原因?我可以看到,如果这些方法相互调用,那将是一个问题,但在这种情况下?

或者,如果这个问题太大而且您认为我需要更多必备知识,那么是否有人有关于语言实现的书籍或网站的任何良好链接,特别是在JVM上?(我知道约翰罗斯的博客,以及编程语言语用学一书......但这就是它.:)



1> Daniel Spiew..:

问题是由于解释器通常必须用给定名称替换现有元素,而不是重载它们.例如,我经常会尝试一些东西,经常创建一个名为的方法test:

def test(x: Int) = x + x

稍后,让我们说我正在运行一个不同的实验,我创建另一个名为的方法test,与第一个无关:

def test(ls: List[Int]) = (0 /: ls) { _ + _ }

这不是一个完全不切实际的场景.事实上,正是大多数人使用解释器的方式,通常都没有意识到.如果解释器任意决定保留test范围内的两个版本,则可能导致使用测试时语义上的混淆.例如,我们可能会打电话test,意外地通过Int而不是List[Int](而不是世界上最不可能发生的事故):

test(1 :: Nil)  // => 1
test(2)         // => 4  (expecting 2)

随着时间的推移,解释器的根范围将变得非常混乱各种版本的方法,字段等.我倾向于让我的解释器一次打开几天,但如果允许这样的超载,我们将被迫"因为事情变得太混乱,所以经常翻译"翻译".

它不是JVM或Scala编译器的限制,而是一个深思熟虑的设计决策.正如bug中所提到的,如果你在根范围之外的其他东西,你仍然可以重载.将测试方法包含在一个类中似乎是对我来说最好的解决方案.



2> psp..:
% scala28
Welcome to Scala version 2.8.0.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def foo(x: Int): Unit = () ; def foo(x: String): Unit = { println(foo(2)) } 
foo: (x: String)Unit  (x: Int)Unit
foo: (x: String)Unit  (x: Int)Unit

scala> foo(5)

scala> foo("abc")
()

推荐阅读
虎仔球妈_459
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有