我正在尝试获取一个函数来编译/在scala中工作,并获得几个绝对无聊的错误消息,我无法理解。如果我像这样编写代码:
def checkUniqueReviewNumber(number: String): Boolean = {
val qc = new QualityClient
if(review.isEmpty)
false
else {
val qrList = qc.listInPL(Vars.currentPLId.get.get,null,null,null,null,null,null,false,false,CurrentUser.getUser.key).qualityReviews
!qrList.exists(qr:QualityReview => qr.reviewNumber == number)
}
}
我收到错误:
.../QualityReviewCreate.scala:189: error: not found: type ==
[scalac] !qrList.exists(qr:QualityReview => qr.reviewNumber == number)
如果我更像这样编写代码:
def checkUniqueReviewNumber(number: String): Boolean = {
val qc = new QualityClient
if(review.isEmpty)
false
else {
val qrList = qc.listInPL(Vars.currentPLId.get.get,null,null,null,null,null,null,false,false,CurrentUser.getUser.key).qualityReviews
!qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number))
}
}
我收到了错误:
... /QualityReviewCreate.scala:189: error: ')' expected but '(' found.
[scalac] !qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number))
[scalac] ^
... /QualityReviewCreate.scala:189: error: ';' expected but ')' found.
[scalac] !qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number))
[scalac] ^
[scalac] two errors found
所涉及的类型可能在这里有所贡献,但如果是这样的话,我完全会对原因感到困惑。 qrList应该是QualityReview的java ArrayList,它是一个带有名为reviewNumber的java String字段的java对象。
有谁知道这里发生了什么?
答案 0 :(得分:22)
问题是Scala使用显式参数类型解析匿名函数是不明确的,有时会导致一些非常奇怪的怪癖。这是其中之一。采用以下表达式:
(qr:QualityReview => qr.reviewNumber == number)
Scala(显然)解析如下:
(qr:(QualityReview => qr.reviewNumber == number))
这不是你想要的。事实上,它甚至不是一个匿名函数。贬低表达式会产生以下结果:
(qr: Function1[QualityReview, ==[qr.reviewNumber, number]])
换句话说,我们将类型归于qr
,其中该类型由Function1
参数化QualityReview
提供,类型由==
参数化类型qr.reviewNumber
和number
。所有这些都是有效的Scala,我怀疑它不是你想要的。
当Scala寻找名称为==
的类型时会出现错误,当然它找不到(可以存在,但它不存在)。如果它已经超过了该错误,那么很快就会遇到查找类型qr.reviewNumber
和number
的问题。
有几种方法可以避免此问题。一般来说,我只是建议在声明你的功能时使用略有不同的风格。 Scala Style Guide是一个很好的起点。对于此函数,解决问题的最简单方法是删除类型注释(QualityReview
)。您也可以通过在qr:QualityReview
周围加上括号来解决问题。此外,我认为冒号之后的空格可能会解决问题,但我无法确定。最后,使用花括号而不是括号通常会使编译器更喜欢将=>
解释为lambda分隔符而不是类型。我会用以下方式编写你的exists
表达式:
!(qrList exists { qr => qr.reviewNumber == number })
实际上,我可能会使用下划线语法,但这是一个完全不同的问题。 : - )
!(qrList exists { _.reviewNumber == number })
答案 1 :(得分:8)
简而言之,您只需在参数列表周围添加括号;即,
!qrList.exists((qr:QualityReview) => qr.reviewNumber == number)
同样适用于.equals的第二次尝试
这是函数糖的一个很好的概述 http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html#funcdef