如何检查一个Matcher片段中的多个表达式?
例如:
class Foo extends Specification {
"Retrieving open issues" should {
"return expected properties with expected data" in {
val issue = Bar.openIssues.head
issue must not beNull
issue.number must beEqualTo(1)
issue.state must beEqualTo("open")
issue.title must beEqualTo("first issue")
}
}
}
给出错误
[error] type mismatch;
[error] found : Int
[error] required: org.specs2.matcher.Matcher[Issue]
[error] issue.number must beEqualTo(1)
Eric引用了this comment中的“经典”类型推断问题,但未找到答案。
答案 0 :(得分:4)
问题出在这一行:
issue must not beNull
因为它是用运算符表示法编写的,所以编译器必须在正确的位置推断出点和圆括号。遵循obj meth arg
与obj.meth(arg)
相同的规则,此行被解释为:
issue.must(not).beNull<missing_arg>
beNull
是在issue.must(not)
的返回值上调用的成员。编译器遵循运算符表示法的规则,并将其视为meth
,而issue.must(not)
被视为obj
。因为运算符表示总是要求调用必须具有obj meth arg
形式,所以在上面的示例中,编译器会因为语法无效而抛出错误。但它没有这样做,因为还有两个规则:
arg
,则会隐式插入空参数列表。由于(1),编译器将下一行视为arg
:
issue.must(not).beNull(
issue.number).must(beEqualTo(1))
这不是代码的解释方式。要解决这个问题,可以将整个表达式括在括号中:
(issue must not beNull)
或用空行分隔线:
issue must not beNull
issue.number must beEqualTo(1)
两个解决方案都有效,因为(2)编译器可以插入一个空参数列表。
注意:如果必须应用(2),这也称为后缀运算符。在2.10中,他们会对警告进行处理,因为 - 正如人们可以看到的那样 - 他们可能会导致棘手的行为。