我在Scala中做了一些编程,我知道,例如,
xs map f
Run Code Online (Sandbox Code Playgroud)
是一样的
xs.map(f)
Run Code Online (Sandbox Code Playgroud)
但我不知道如何将这种语法概括为像ScalaTest的语法,例如,
it should "throw NoSuchElementException if an empty stack is popped" in {
val emptyStack = new Stack[String]
evaluating { emptyStack.pop() } should produce [NoSuchElementException]
}
Run Code Online (Sandbox Code Playgroud)
我主要想知道看起来像多字构造的东西,即should produce.它很整洁.
Bil*_*ers 13
这种语法是运算符表示法中的方法调用,但不仅仅是三个令牌.正如你已经提到的:
xs map f
Run Code Online (Sandbox Code Playgroud)
手段:
xs.map(f)
Run Code Online (Sandbox Code Playgroud)
但你可以进一步说:
xs map f map g
Run Code Online (Sandbox Code Playgroud)
意思是:
xs.map(f).map(g)
Run Code Online (Sandbox Code Playgroud)
例如,在ScalaTest匹配器中,您可以说:
result should not be null
Run Code Online (Sandbox Code Playgroud)
这会被编译器贬低为:
result.should(not).be(null)
Run Code Online (Sandbox Code Playgroud)
这个:
it should "throw an exception" in { ... }
Run Code Online (Sandbox Code Playgroud)
变得卑鄙:
it.should("throw an exception").in { ... }
Run Code Online (Sandbox Code Playgroud)
最后的花括号实际上只是一种将花括号(测试代码)之间的代码传递给in方法的方法,包装为无参数函数.所以这些都是同一个想法.运算符表示法连续使用两次.
你问过的最后一个有点不同:
evaluating { ... } should produce [IllegalArgumentException]
Run Code Online (Sandbox Code Playgroud)
这变成了:
evaluating { ... }是的,首先评估,因为花括号使它优先.这是一个方法调用,您正在调用一个名为"evaluate"的方法,将花括号之间的代码作为无参数函数传递.返回一个应该调用的对象.所以应该是通过调用求值返回的对象的方法.实际需要的是调用产品的结果.这里产生的实际上是一个方法,它有一个类型参数,如should.它必须以这种方式完成,因此Scala编译器可以"穷人 - 实现"该类型参数.它将隐式"Manifest"参数传递给可以为其提供should实例的产品evaluating.因此,当调用方法时,它有一个包含传递给求值的代码的函数,以及一种查找should放在方括号中的异常类型的方法.因此它执行try中包含的代码块,捕获异常,将其与预期进行比较.如果没有抛出异常或错误的异常,则should方法抛出TestFailedException.否则,should方法只是静默返回.
所以,答案就是这条线被玷污了:
(evaluating { ... }).should(produce[IllegalArgumentException] (compilerSuppliedManifest))
Run Code Online (Sandbox Code Playgroud)
故事的寓意是,像这样的高级代码使得更容易看到程序员的意图,但往往更难理解代码的实际工作方式.在实践中大部分时间你所关心的只是意图,但是你需要知道某些东西是如何工作的.在Scala中的这种情况下,您可以将-Xprint:typer作为命令行arg传递给Scala编译器,它将在所有desugaring发生后打印出您的文件版本.所以你可以在需要时看到什么.
| 归档时间: |
|
| 查看次数: |
1745 次 |
| 最近记录: |