Scala使用不同的返回类型提供相同的方法和参数

Scala使用不同的返回类型提供相同的方法和参数,scala,Scala,我在Scala 2.10.2上,试图定义一个特征,比如 trait Foo { def bar(a:String): String def bar(a:String): Int } 获取编译器错误方法a定义了两次。正确的语法是什么?在JVM上,方法的返回类型不是方法签名的一部分。您必须提供不同的方法名称或参数。来自Oracle: 定义:方法声明的两个组件组成 方法签名方法的名称和参数类型 您正在尝试的是方法重载,Oracle说: 编译器在区分时不考虑返回类型 方法,因此不能声明具有相同

我在Scala 2.10.2上,试图定义一个特征,比如

trait Foo {
  def bar(a:String): String
  def bar(a:String): Int
}

获取编译器错误
方法a定义了两次
。正确的语法是什么?

在JVM上,方法的返回类型不是方法签名的一部分。您必须提供不同的方法名称或参数。来自Oracle:

定义:方法声明的两个组件组成 方法签名方法的名称和参数类型

您正在尝试的是方法重载,Oracle说:

编译器在区分时不考虑返回类型 方法,因此不能声明具有相同签名的两个方法 即使他们有不同的返回类型


因为Scala也编译成JVM字节码,规则在JVM上是相同的。方法的返回类型不是方法签名的一部分。您必须提供不同的方法名称或参数。来自Oracle:

定义:方法声明的两个组件组成 方法签名方法的名称和参数类型

您正在尝试的是方法重载,Oracle说:

编译器在区分时不考虑返回类型 方法,因此不能声明具有相同签名的两个方法 即使他们有不同的返回类型

因为Scala也编译为JVM字节码,规则与wiki中的相同:

仅具有不同的返回类型不算作函数重载,这是不允许的。

来自wiki:


仅具有不同的返回类型不算作函数重载,这是不允许的。

只需轻轻推拉即可

trait Foo {
  def bar(a:String): String
  def bar(a:String)(implicit di: DummyImplicit): Int
}

class F extends Foo {
  def bar(a: String): String = "Hello"
  def bar(a: String)(implicit di: DummyImplicit): Int = 1
}

object Demo extends App {
  val f = new F()
  val s: String = f.bar("x")
  val i: Int = f.bar("x")
  println(s)
  println(i)
}

您可以使用
DummyImplicit
(绕过“方法定义两次”)和显式键入(选择其中一种方法)来调整它。

,只需轻轻推拉即可

trait Foo {
  def bar(a:String): String
  def bar(a:String)(implicit di: DummyImplicit): Int
}

class F extends Foo {
  def bar(a: String): String = "Hello"
  def bar(a: String)(implicit di: DummyImplicit): Int = 1
}

object Demo extends App {
  val f = new F()
  val s: String = f.bar("x")
  val i: Int = f.bar("x")
  println(s)
  println(i)
}

您可以使用
DummyImplicit
(绕过“方法定义两次”)和显式键入(选择其中一种方法)对其进行调整。

我真的不知道为什么它会有用,但您可以这样做:

scala> object Foo {
     | trait BarImpl[T] { def apply(str: String): T }
     | implicit object barInt extends BarImpl[Int] { def apply(str: String) = 1 }
     | implicit object barBoolean extends BarImpl[Boolean] { def apply(str: String) = true }
     | def bar[T](str: String)(implicit impl: BarImpl[T]) = impl(str)
     | }
defined module Foo

scala> Foo.bar[Int]("asdf")
res8: Int = 1

scala> Foo.bar[Boolean]("asdf")
res9: Boolean = true

我真的不知道为什么它会有用,但你可以这样做:

scala> object Foo {
     | trait BarImpl[T] { def apply(str: String): T }
     | implicit object barInt extends BarImpl[Int] { def apply(str: String) = 1 }
     | implicit object barBoolean extends BarImpl[Boolean] { def apply(str: String) = true }
     | def bar[T](str: String)(implicit impl: BarImpl[T]) = impl(str)
     | }
defined module Foo

scala> Foo.bar[Int]("asdf")
res8: Int = 1

scala> Foo.bar[Boolean]("asdf")
res9: Boolean = true

与Java一样,也没有基于返回类型的多态性。与此相关的问题是,在Java中,不存在基于返回类型的多态性。严格来说,JVM并没有阻止这一点。在JVM级别,返回类型是方法签名的一部分,因此您可以创建两个名称和参数类型相同但返回类型不同的方法(至少在字节码级别)。然而,Java不支持这一点(没有机制来区分它们),Scala通常会避免破坏Java互操作性,严格来说,JVM不会阻止这一点。在JVM级别,返回类型是方法签名的一部分,因此您可以创建两个名称和参数类型相同但返回类型不同的方法(至少在字节码级别)。然而,Java不支持这一点(没有区分它们的机制),Scala通常避免破坏Java互操作性。