为什么Scala的predef中的require方法允许String作为参数?

Joh*_*ood 6 scala

我可以在Scala的Predef类中使用require方法,并将String作为第二个参数,例如

require ("foo" == "bar", "foobar")
Run Code Online (Sandbox Code Playgroud)

首先考虑将require方法作为第二个参数重载为不同的参数.但事实并非如此.require方法的签名(Scala 2.9.1)是:

require(requirement: Boolean, message: ? Any): Unit
Run Code Online (Sandbox Code Playgroud)

为什么上述方法调用可能?

Tom*_*icz 21

我不完全理解这个问题,但这里有一点解释.require有一个重载版本Predef:

def require(requirement: Boolean) //...
def require(requirement: Boolean, message: => Any) //...
Run Code Online (Sandbox Code Playgroud)

第二个因message: => Any类型而有点混乱.如果简单的话可能会更容易:

def require(requirement: Boolean, message: Any) //...
Run Code Online (Sandbox Code Playgroud)

第二个参数当然是一条消息,如果不满足断言,则假定将其附加到错误消息中.你可以想象message应该是String类型,但Any你可以简单地写:

require(x == 4, x)
Run Code Online (Sandbox Code Playgroud)

如果它不等于,则会将x(of type Int)的实际值添加到错误消息中4.这就是为什么Any被选中 - 允许任意价值.

但那: =>部分呢?这称为名称调用,基本上意味着:在访问它时评估此参数.想象一下以下片段:

require(list.isEmpty, list.size)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您要确保它list是空的 - 如果不是,请将实际list大小添加到错误消息中.但是,对于正常的调用约定,list.size必须在调用方法之前评估该部分- 这可能是浪费的.随着按名称调用约定list.size只计算第一次使用-当错误消息的构造函数(如果需要).