来自Scala的参数列表中带有“...”的Java函数

时间:2011-08-26 13:09:35

标签: java scala variadic-functions

如上所述here

如果您想编译代码,则必须将:_*关键字添加到condition:Predicate

现在我遇到了这个问题

val queryBuilder = em.getCriteriaBuilder()
     val cq = queryBuilder.createQuery(classOf[Product])
     val product:Root[Product] = cq.from(classOf[Product])
     val condition:Predicate = queryBuilder.equal(product.get("name"), "name")
     --> cq.where(condition:_*)


Multiple markers at this line
- type mismatch; found : javax.persistence.criteria.Predicate required: Seq[?]

有什么想法吗?

3 个答案:

答案 0 :(得分:8)

您不能在此使用:_*

_*存在的原因是varargs可能会导致含糊不清。 在java中如果您有f(int... values),可以致电f(1, 2, 3),但也可以

int[] values = {1, 2, 3}; 
f(values)

有了整数,没关系。但是如果你有f(object.. values)并拥有object[] values = {"a", "b"},那么在调用f(values)时,是否意味着使用单个arg(values或多个args)调用f "a""b"? (java选择后者)。

为了避免这种情况,在scala中,当存在varargs时,不允许将它们作为数组传递(实际上是scala中更通用的Seq)参数,除非你明确说明你是这样做的,放弃了:_*。在前面的示例中,f(values)表示值是单个参数。 f(values: _*)表示值的每个元素,无论是零,一个还是多个,都是一个参数。

在您的特定情况下,您将Predicate个参数(实际上只是一个)作为单独的(well ...)谓词传递,而不是谓词集合。所以没有:_*

修改:我仔细阅读了您关联的帖子。虽然我当然相信我上面写的是真的,但它可能没什么帮助。 MxFr给出了正确的答案:

  1. 从scala 2.9开始,与java varargs的交互就可以了。只是通过条件
  2. 在此之前,您必须将参数作为数组传递,并放入:_ *

答案 1 :(得分:3)

使用Scala 2.9 cq.where(condition)应该有效,即使cq.where(condition1, condition2)也可以。

或者您可以使用cq.where(Array(condition):_*)

答案 2 :(得分:0)

我正在使用scala库2.9.0.1。这是该代码的编译器错误,只传递条件:

[ERROR]     D:\Mazi\Develop\workspaces\scala\sshwWebApp\src\main\scala\com\example\app\dao\DefaultProductDao.scala:54: error: ambiguous referenc
    e to overloaded definition,
    [INFO] both method where in trait CriteriaQuery of type (x$1: <repeated...>[javax.persistence.criteria.Predicate])javax.persistence.criteria
    .CriteriaQuery[com.example.app.domain.Product]
    [INFO] and  method where in trait CriteriaQuery of type (x$1: javax.persistence.criteria.Expression[java.lang.Boolean])javax.persistence.cri
    teria.CriteriaQuery[com.example.app.domain.Product]
    [INFO] match argument types (javax.persistence.criteria.Predicate)
    [INFO]      cq.where(condition)
    [INFO]         ^

问题出在哪里?

如果我使用

cq.where(Array(condition):_*)

我收到相同的编译错误:

[ERROR] D:\Mazi\Develop\workspaces\scala\sshwWebApp\src\main\scala\com\example\app\dao\DefaultProductDao.scala:54: error: ambiguous referenc
e to overloaded definition,
[INFO] both method where in trait CriteriaQuery of type (x$1: <repeated...>[javax.persistence.criteria.Predicate])javax.persistence.criteria
.CriteriaQuery[com.example.app.domain.Product]
[INFO] and  method where in trait CriteriaQuery of type (x$1: javax.persistence.criteria.Expression[java.lang.Boolean])javax.persistence.cri
teria.CriteriaQuery[com.example.app.domain.Product]
[INFO] match argument types (javax.persistence.criteria.Predicate)
[INFO]      cq.where(Array(condition):_*)
[INFO]         ^

也许我使用的scala编译器?

KInd问候 马西莫