为什么语言不允许通过返回值重载方法?

时间:2009-10-20 18:55:17

标签: language-design

c,java和许多其他语言都不注意返回值。

int   i = func()
float f = func()
int   func() { return 5 }
float func() { return 1.3}

为什么以上不合法?是否使编程更加困难

int i = func(func(func(func2(func3())))) //you dont know what you are getting

编写编译器难吗?还有更多语言的歧义吗?有没有可以做到的上述语言?

8 个答案:

答案 0 :(得分:17)

这个案子怎么样?

class A implements Foo { /*...*/ }
class B implements Foo { /*...*/ }

A func() { return new A(); }
B func() { return new B(); }

Foo v = func(); // which do you call?!

当允许重载具有不同参数的单个函数名时,已存在歧义问题。必须检查返回类型可能会使解决正确的功能变得更加困难。

我确信一种语言可以实现这一点,但它会使事情变得更复杂,并且通常会使代码更难理解。

答案 1 :(得分:14)

让我们说这是允许的,这可以称之为:

func();

这可能不是完整的答案,但我认为这是不合法的原因之一。

答案 2 :(得分:10)

是的,允许在返回类型上重载会使语言复杂化。它使重载标识符(例如函数名称)的解析变得复杂。但这并非不可能,例如Haskell允许根据返回类型重载函数。

class Num a where
  fromInteger :: Integer -> a 
  ...

Num是Haskell中的一个类型类,它有一个名为fromInteger的方法,它是一个从任意大小Integer到任意类型的函数,其实例为Num 。 Haskell类型类机制与面向对象语言的类概念有很大不同。因此我的解释可能听起来很奇怪

但是,结果是我可以使用fromInteger函数,并且根据调用上下文,在编译时可以选择不同的实现。

对类型系统进行了全面的研究,使这一特性成为可能。因此,我认为它在静态类型语言中是可行的。动态类型语言需要时间旅行或一些聪明的想法。

答案 3 :(得分:9)

避免含糊不清。

a( int )
a( bool )
int b()
bool b()

a( b() ) -- Which b?

这里类型推断具有循环依赖性。哪个b取决于aa取决于哪个b,因此会卡住。

禁止重载类型的重载可确保类型推断是非循环的。返回类型始终可以由参数类型确定,但参数类型不能由返回类型确定,因为它们可能又由您尝试查找的参数类型确定。

答案 4 :(得分:6)

对于C ++示例,请考虑:

void g(int x);
void g(float x);
g(func());

将调用哪些重载的g()函数?

答案 5 :(得分:3)

Perl允许一定程度的返回类型变化,因为函数可以告诉他们正在评估它们的上下文类型。例如,可能返回数组的函数可以看到它在标量上下文中运行,并且只是直接返回推定的长度,节省数组的分配和初始化只是为了得到它的长度。

答案 6 :(得分:1)

大多数语言允许使用自动强制的混合模式操作(例如float + int),其中多种解释是合法的。没有强制,使用多种数字类型(short,int,long,float,double)会变得非常麻烦;在强制下,基于回归类型的歧义将导致难以理解的代码。

答案 7 :(得分:1)

允许这些可能会带来问题。 例如:

int i = func2(func());
int func() { return 5; }
float func() { return 1.3; }
int func2(float a) { return a; }
int func2(int a) { return a; }

这是不明确的。