为什么 Scala 编译器不允许使用默认参数的重载方法? [英] Why does the Scala compiler disallow overloaded methods with default arguments?

查看:38
本文介绍了为什么 Scala 编译器不允许使用默认参数的重载方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然在某些情况下,此类方法重载可能会变得模棱两可,但为什么编译器不允许在编译时和运行时既不模棱两可的代码呢?

While there might be valid cases where such method overloadings could become ambiguous, why does the compiler disallow code which is neither ambiguous at compile time nor at run time?

示例:

// This fails:
def foo(a: String)(b: Int = 42) = a + b
def foo(a: Int)   (b: Int = 42) = a + b

// This fails, too. Even if there is no position in the argument list,
// where the types are the same.
def foo(a: Int)   (b: Int = 42) = a + b
def foo(a: String)(b: String = "Foo") = a + b

// This is OK:
def foo(a: String)(b: Int) = a + b
def foo(a: Int)   (b: Int = 42) = a + b    

// Even this is OK.
def foo(a: Int)(b: Int) = a + b
def foo(a: Int)(b: String = "Foo") = a + b

val bar = foo(42)_ // This complains obviously ...

为什么这些限制不能放宽一点?

Are there any reasons why these restrictions can't be loosened a bit?

特别是在将重载的 Java 代码转换为 Scala 的默认参数时,这是一个非常重要的问题,在用一个 Scala 方法替换大量 Java 方法后发现规范/编译器施加了任意限制并不好.

Especially when converting heavily overloaded Java code to Scala default arguments are a very important and it isn't nice to find out after replacing plenty of Java methods by one Scala methods that the spec/compiler imposes arbitrary restrictions.

推荐答案

我想引用 Lukas Rytz(来自 此处):

I'd like to cite Lukas Rytz (from here):

原因是我们想要一个确定性的命名方案生成的方法返回默认参数.如果你写

The reason is that we wanted a deterministic naming-scheme for the generated methods which return default arguments. If you write

def f(a: Int = 1)

编译器生成

def f$default$1 = 1

如果在同一个参数上有两个带有默认值的重载位置,我们需要一个不同的命名方案.但我们想保持生成的字节码在多次编译器运行中稳定.

If you have two overloads with defaults on the same parameter position, we would need a different naming scheme. But we want to keep the generated byte-code stable over multiple compiler runs.

未来 Scala 版本的解决方案可能是将非默认参数的类型名称(在方法开头的那些,消除重载版本的歧义)合并到命名模式中,例如在这种情况下:

A solution for future Scala version could be to incorporate type names of the non-default arguments (those at the beginning of a method, which disambiguate overloaded versions) into the naming schema, e.g. in this case:

def foo(a: String)(b: Int = 42) = a + b
def foo(a: Int)   (b: Int = 42) = a + b

它会是这样的:

def foo$String$default$2 = 42
def foo$Int$default$2 = 42

有人愿意编写 SIP 提案?

这篇关于为什么 Scala 编译器不允许使用默认参数的重载方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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