为什么Ruby不支持方法重载?

7 浏览
0 Comments

为什么Ruby不支持方法重载?

Ruby不支持方法重载,而是覆盖已有的方法。有人能解释一下为什么这门语言被设计成这样吗?

0
0 Comments

为什么Ruby不支持方法重载?

Ruby不支持方法重载的原因是因为它根本不支持静态分派。无论是基于参数还是其他方式的静态分派,Ruby都不支持任何形式的静态分派。如果你不是在特别问方法重载,而是关于动态基于参数的分派,那么答案是:因为Matz没有实现它,因为没有其他人提出它,也没有其他人去实现它。

对于带有可选参数和可变长度参数列表的语言来说,基于参数的动态分派非常难以实现,并且更难以保持可理解性。即使在仅具有静态基于参数分派且没有可选参数的语言(例如Java)中,有时也几乎不可能对于一个普通人来说确定哪个重载将被选择。

在C#中,你实际上可以将任何3-SAT问题编码为重载解析,这意味着C#中的重载解析是NP难问题。

现在尝试在具有额外时间维度的动态调度中实现这一点。

有一些语言根据过程的所有参数(而不仅仅是面向对象的语言中的“隐藏”的第0个self参数)进行动态调度。例如,Common Lisp根据所有参数的动态类型甚至动态值进行调度。Clojure根据所有参数的任意函数进行调度(这是非常酷和非常强大的)。

但是我不知道有任何具有基于动态参数的动态调度的面向对象语言。Martin Odersky表示,他可能会考虑在Scala中添加基于参数的调度,但前提是他能同时删除重载,并且与使用重载的现有Scala代码向后兼容并且与Java兼容(他特别提到了Swing和AWT,这些代码对Java相当复杂的重载规则进行了一些非常复杂的处理)。

我自己也有一些关于在Ruby中添加基于参数的调度的想法,但我从未找到过以向后兼容的方式实现它的方法。

这是正确的答案。接受的答案过于简单。C#确实具有命名参数和可选参数,并且仍然实现了重载,所以问题不是“def method(a, b = true)不能工作,因此方法重载是不可能的”。问题并不简单。然而,我确实发现这个答案非常有启发性。

只是为了给出一个关于在C#中“困难”重载解析的一些想法......可以将任何3-SAT问题编码为C#中的重载解析,并使编译器在编译时解决它,从而使C#中的重载解析成为NP难问题(已知3-SAT是NP完全问题)。现在想象一下,不是在编译时每个调用点执行一次,而是在运行时每个方法调用执行一次。

我知道这是一个旧问题和答案,但是是否可能根据在重载函数内部调用的函数参数进行鸭子类型,让编译器选择要使用的重载函数?只是好奇...

örgWMittag,你能包含一个在重载解析机制中显示3-SAT问题编码的链接吗?

blogs.msdn.com/b/ericlippert/archive/2007/03/28/…

“重载”不是“静态基于参数的分派”的同义词。静态基于参数的分派只是重载的最常见实现。重载是一个与实现无关的术语,意思是“在相同范围内使用相同方法名但不同实现”。

另一个动态语言Elixir可以优雅地处理方法重载:可以使用不同数量的参数或使用模式匹配。这在函数式编程世界中非常常见,但在Ruby中却很遗憾地缺失了。

0
0 Comments

为什么Ruby不支持方法重载?

方法重载是指在同一个类中,可以定义多个同名方法,但是它们的参数列表不同。然而,Ruby不支持方法重载,原因如下:

1. Ruby的设计理念是简洁和灵活。Ruby的创造者认为方法重载会增加代码的复杂性和理解难度,不符合Ruby的哲学。

2. Ruby使用动态类型系统,方法的参数类型可以在运行时动态确定。因此,Ruby不需要通过方法重载来实现静态类型检查。

3. Ruby提供了其他方法来解决相同的问题。例如,可以使用可变参数(*args)来接受不同数量的参数,并在方法内部根据参数的长度来执行不同的逻辑。也可以使用选项哈希(options hash)来传递参数,并在方法内部根据哈希的键值对执行不同的逻辑。

虽然Ruby不直接支持方法重载,但上述的解决方法可以达到类似的效果。通过使用可变参数或选项哈希,可以实现接受不同数量或类型的参数,并根据参数的不同执行不同的逻辑。

,Ruby不支持方法重载是因为它的设计理念、动态类型系统以及提供的其他解决方案。使用可变参数或选项哈希可以达到类似的效果。

0
0 Comments

Ruby不支持方法重载的原因是因为它是一种动态类型语言,无法使用第一种方式实现方法重载,即通过不同的数据类型来区分方法。因此,我们只能使用def(a,b)的方式来定义上述方法。

对于第二种方式,虽然看起来可以实现方法重载,但实际上却不行。假设我有两个具有不同参数数量的方法:

def method(a); end;
def method(a, b = true); end; # 第二个参数有默认值
method(10)
# 现在方法调用可以匹配第一个方法和第二个方法,这就是问题所在。

因此,Ruby需要在方法查找链中维护一个具有唯一名称的方法。

对于解决方法,可以使用Contracts gem来实现方法重载,具体请参考Ekins的答案:egonschiele.github.io/contracts.ruby/#method-overloading。

总之,由于Ruby是一种动态类型语言,无法通过数据类型来区分方法,因此不支持方法重载。

0