我在Scala 2.10.2上尝试定义像
这样的特征trait Foo {
def bar(a:String): String
def bar(a:String): Int
}
获取编译器错误method a is defined twice
。什么是正确的语法?
答案 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.
只有不同的返回类型不计入函数重载,并且不允许。