为什么 dart 不允许方法重载?

log*_*l48 4 dart

我尝试在一些 dart 代码中使用方法重载,并很快了解到 dart 中不提供重载。

我的问题是:为什么不提供它,推荐的替代方案是什么?是否存在标准命名约定,因为执行相同操作但具有不同输入的方法必须具有不同的名称?

使用命名参数然后检查调用者是否提供了足够的信息来完成计算是否标准?

假设我有一个方法可以返回某人一年赚多少钱,称为yearlyIncome.

在 Java 中,我会创建一个这样的方法

double yearlyIncome(double hourlyRate, double hoursWorkedPerYear)
Run Code Online (Sandbox Code Playgroud)

也许另一种方法是这样的

double yearlyIncome(double monthlyRate, int monthsWorkedPerYear)
Run Code Online (Sandbox Code Playgroud)

等等。它们都用于计算相同的东西,但具有不同的输入。在 dart 中执行此操作的最佳标准化方法是什么?

非常感谢。

lrn*_*lrn 8

Dart 最初不支持重载,因为它是一种更加动态的语言,其中声明的类型没有任何语义效果。这使得无法使用基于静态类型的重载解析。

此后 Dart 变得更加静态,并且没有什么从根本上阻止 Dart 今天添加重载,除了这将是一项巨大的工作以及对语言的巨大改变。或者说我是这么认为的,因为没有任何明显的设计不是高度复杂的,就是巨大的破坏性的。

在 Dart 中您要做的是使用可选参数。像这样的方法:

String toString([int radix]);
Run Code Online (Sandbox Code Playgroud)

实际上有两个签名:String Function()String Function(int)。它可以对两个签名起作用。仅使用可选参数可以走多远有明确的限制,因为它们仍然需要每个都只有一种类型,但这是 Dart 目前提供的替代方案。(或者使用不同的名称,但这不是重载,您也可以在具有重载的语言中做到这一点)。

如果我们想向 Dart 语言添加重载,可选参数也是复杂的问题之一 - 具有可选参数的现有函数会被视为多次重载吗?如果你声明一个类:

abstract class WithOverloading {
  String toString();
  String toString(int radix);
}
Run Code Online (Sandbox Code Playgroud)

那是与以下相同的签名:

abstract class WithoutOverloading {
  String toString([int radix]);
}
Run Code Online (Sandbox Code Playgroud)

可能不是,因为您可以剥离后者并获得一个带有可选参数的函数,并且您可能无法剥离前者的两个函数并将它们组合成一个函数。或者也许你可以,这就是为什么如何将重载包含到现有的 Dart 语言中并不是一个简单的设计问题。


bar*_*ecu 7

Dart 根本不支持函数重载。函数重载需要静态类型。Dart 的核心是一种动态类型语言。

您可以为方法或可选的命名或未命名参数使用不同的名称

// optional unnamed
void foo(int a, [String b]);

foo(5);
foo(5, 'bar');

// optional named
void foo(int a, {String b});

foo(5);
foo(5, b :'bar');
Run Code Online (Sandbox Code Playgroud)

可选参数也可以有默认值。可选的命名和未命名参数不能一起使用(单个函数只能使用一个或另一个)在构造函数的情况下,您可以使用命名构造函数作为替代