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



考虑:

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>

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

Scala允许您在重写时更改参数的名称(尽管不鼓励),但如果调用方愿意,您总是需要提供一个名称供其使用。

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

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

我没有研究语言规范,但可以放心地假设方法参数应该是名称标识符,而_不是有效的名称标识符。

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

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

最新更新