scala - 编译器无法识别函数重载,因为类型已被删除。如何克服这一点?

标签 scala parametric-polymorphism

我有一个问题,下面代码中名为 fooSome 的两个方法无法编译,因为编译器报告了方法名称重复的问题:

class Foo() {

  // variable block has 2 closure variables
  def fooSome(block: Some[(Int, String) => Unit]) = {

  }

  // variable block has 1 closure variables
  def fooSome(block: Some[Int => Unit]) = {

  }

  // variable block has 2 closure variables
  def fooNoSome(block: (Int, String) => Unit) = {

  }

  // variable block has 1 closure variables
  def fooNoSome(block: Int => Unit) = {

  }
}

相反,编译器报告没有与名为 fooNoSome 的两个方法发生此类方法名称冲突。所以问题是编译器没有看到“Some[( Int, String ) => Unit]”和“Some[( Int ) => Unit]”之间的区别"而 "( Int, String ) => Unit"被视为与 fooNoSome 方法的 "( Int ) => Unit"不同的签名。

我可以通过创建一个用于“Some[(Int, String) => Unit]”案例的类 Some2Args 和一个用于“Some[(Int) => Unit]”案例的类 Some1Arg 来解决这个问题。

我的问题是是否有更优雅、更省力的解决方案。

最佳答案

编译器确实看到了它们之间的差异,只是不允许在重载中使用这种差异(因为 Some[(Int, String) => Unit]Some[Int => Unit] 的删除是相同的,并且当参数删除相同时,JVM 不允许重载)。解决方案是添加假的隐式参数:

class Foo() {
  def fooSome(block: Some[(Int, String) => Unit]) = {

  }

  def fooSome(block: Some[Int => Unit])(implicit d: DummyImplicit) = {

  }
}

还要注意 fooNoSome 的删除是 fooNoSome(Function2)fooNoSome(Function1) ,所以如果你想添加另一个带有一个或两个参数的函数的重载,你需要 DummyImplicit再骗一次:
  def fooNoSome(block: Double => Unit)(implicit d: DummyImplicit) = ...

关于scala - 编译器无法识别函数重载,因为类型已被删除。如何克服这一点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21375827/

相关文章:

scala - 如何解释 RDD.treeAggregate

scala - 我们真的在 Scala 中拥有 'extend' 特征吗?

haskell - 为什么是forall a。 a 不被视为 Int 的子类型,而我可以使用 forall a 类型的表达式。任何地方都需要 Int 类型?

haskell - 智能构造函数类型可以有多个有效的 Functor 实例吗?

tree - 在折叠树的 Typed Racket 中转换到任意类型

scala - 如何在Play Framework中配置线程池优先级

json - Play JSON可选转换器

scala - 在 scala 中将 Int 添加到字符串

haskell - Data.Foldable 用于无序容器

haskell - 哪个是多态类型 : a type or a set of types?