考虑:
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、部分方法应用程序和模式匹配。
我没有研究语言规范,但可以放心地假设方法参数应该是名称标识符,而_
不是有效的名称标识符。
这里有一个更详细的解释:
_
与lambdas一起工作的原因是lambdas无论如何都不可能具有命名参数- 如果通过父类类型(
Foo
)的引用对子类(Baz
)实例进行多态调用,Scala将简单地将父类方法名称(arg0
)"继承"到子类中,这样多态调用就不会在Baz#bar
中看到更改后的名称blabla
- 然而,子类方法仍然需要直接调用,因此它确实需要为其参数提供有效的名称,因此
_
由于明显的原因而不起作用;还建议这些方法与父类方法名相匹配,为了清楚起见,父类方法名称被重写