Scala使用不同的返回类型来表示相同的方法和参数

时间:2013-07-26 18:59:47

标签: scala

我在Scala 2.10.2上尝试定义像

这样的特征
trait Foo {
  def bar(a:String): String
  def bar(a:String): Int
}

获取编译器错误method a is defined twice。什么是正确的语法?

4 个答案:

答案 0 :(得分:8)

稍微推拉

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(绕过“方法定义两次”)和显式输入(选择其中一种方法)。

答案 1 :(得分:6)

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

  

定义:方法声明的两个组成部分包括   方法签名 - 方法的名称和参数类型。

您尝试做的事情称为方法重载,Oracle说如下:

  

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

原因Scala也编译为JVM字节码,规则是相同的

答案 2 :(得分:3)

我无法确定为什么它会有用,但你可以这样做:

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

答案 3 :(得分:2)

来自wiki:http://en.wikipedia.org/wiki/Function_overloading

Rules in function overloading

* The overloaded function must differ either by the arity or data types.
* The same function name is used for various instances of function call.

只有不同的返回类型不计入函数重载,并且不允许。