简体   繁体   English

Scala特征相同的方法和参数具有不同的返回类型

[英]Scala trait same method and argument with different return types

I am on Scala 2.10.2 and trying to define a trait like 我在Scala 2.10.2上并尝试定义一个像

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

Getting a compiler error method a is defined twice . 获取编译器错误method a is defined twice What's the correct syntax? 正确的语法是什么?

With a little push and pull 稍微推拉

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)
}

you can tweak it, using a DummyImplicit (to get around "Method is defined twice") and explicit typing (to pick one of the methods). 您可以使用DummyImplicit (绕过“两次定义方法”)和显式键入(选择其中一种方法)进行调整。

On the JVM the return type of a method is not a part of a method signature. 在JVM上,方法的返回类型不是方法签名的一部分。 You have to give different method names or parameters. 您必须提供不同的方法名称或参数。 From Oracle Docs : 从Oracle Docs

Definition: Two of the components of a method declaration comprise the method signature—the method's name and the parameter types. 定义:方法声明的两个组成部分包括方法签名-方法的名称和参数类型。

What you are tryng to do is called Method overloading and Oracle says the following: 您尝试执行的操作称为方法重载,Oracle表示以下内容:

The compiler does not consider return type when differentiating methods, so you cannot declare two methods with the same signature even if they have a different return type. 区分方法时,编译器不会考虑返回类型,因此即使两个方法具有不同的返回类型,也无法声明具有相同签名的两个方法。

Cause Scala also compiles to JVM byte code, rules are the same 原因Scala也编译为JVM字节码,规则相同

I can't really tell why it would be useful, but you could do this: 我真的不能说出它为什么有用,但是您可以这样做:

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

From wiki: http://en.wikipedia.org/wiki/Function_overloading 从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.

Only having different return types does not count as function overloading, and is not allowed. 仅具有不同的返回类型不会被视为函数重载,并且不允许这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM