为什么不能用#表示方法覆盖中未使用/忽略的参数?

时间:2014-11-10 13:30:10

标签: scala

考虑:

trait Validation {
  def isValid(str: String): Boolean
}
class AlwaysValid extends Validation {
  override def isValid(_: String) = true
}

产量

<console>:1: error: identifier expected but '_' found.
       override def isValid(_: String) = true

任何想法为什么?或者这只是语言设计师错过的东西?


也许这是关于命名参数传递但这只适用于非覆盖,因为覆盖自动“继承”来自重写方法的参数名称,所以这不可能是:

trait Foo {
  def bar(arg0: String): String
}
class Baz extends Foo {
  override def bar(blabla: String) = "hello"
}

new Baz().bar(arg0 = "world")  // works, even though the arg name is blabla in Baz

此外: _在lambdas中被允许,甚至多次:

scala> val x: Int => Int = _ => 3
x: Int => Int = <function1>

scala> val x: (Int, Int) => Int = (_, _) => 3
x: (Int, Int) => Int = <function2>

3 个答案:

答案 0 :(得分:6)

因为在调用方法时可以使用参数名称。

Scala允许您在覆盖时更改参数的名称(尽管不鼓励)但是您总是需要提供一个名称供调用者使用,如果他们愿意的话。

答案 1 :(得分:3)

这里有一个更详细的解释:

  1. _与lambdas一起工作的原因是lambdas无论如何都不能拥有命名参数。
  2. 如果通过父类类型(Baz)的引用对子类(Foo)实例进行多态调用,Scala将简单地继承&#34;继承&#34;父类方法名称(arg0)进入子类,因此多态调用不会在blabla中看到更改后的名称Baz#bar;
  3. 但是,子类方法仍然需要直接调用,因此它需要为其参数提供有效的名称,因此_因为显而易见的原因而无法工作;它还建议那些匹配父类方法名称,为了清楚起见而被覆盖。

答案 2 :(得分:2)

我认为这只是一个语法问题。

_是scala中的一个特殊标识符,在一组明确定义的情况下允许使用它,例如lambdas,部分方法应用程序和模式匹配。

我没有查看语言规范,但可以安全地假设方法参数应该是名称标识符,_不是有效的。