为什么scala:_ *将Seq扩展为可变长度参数列表在这种情况下不起作用?

时间:2013-04-09 14:06:50

标签: scala playframework-2.0 anorm

为什么scala :_*将Seq扩展为可变长度参数列表在这种情况下不起作用?

如何优雅地解决它?

import java.sql.Connection
import scalikejdbc.ConnectionPool
import anorm.{SQL, SqlQuery, SqlRow, Row}

object AnormExample extends App {
  Class.forName("org.hsqldb.jdbc.JDBCDriver")
  ConnectionPool.singleton("jdbc:hsqldb:mem:hsqldb:WithAnorm", "", "")
  implicit val conn: Connection = ConnectionPool.borrow()

  // this works
  SQL("insert into emp (id, name) values ({id}, {name})").onParams(3, "name3").executeUpdate()  

  // this does not compile
  val row = Seq(4, "name4")
  SQL("insert into emp (id, name) values ({id}, {name})").onParams(row:_*).executeUpdate()  // david
}

错误:

scala: type mismatch;
 found   : Seq[Any]
 required: Seq[anorm.ParameterValue[?]]
  SQL("insert into emp (id, name) values ({id}, {name})").onParams(row:_*).executeUpdate()  // david

PS:

<dependency>
  <groupId>play</groupId>
  <artifactId>anorm_2.10</artifactId>
  <version>2.1.1</version>
</dependency>

<dependency>
  <groupId>com.github.seratch</groupId>
  <artifactId>scalikejdbc_2.10</artifactId>
  <version>1.5.1</version>
</dependency>

<dependency>
  <groupId>org.hsqldb</groupId>
  <artifactId>hsqldb</artifactId>
  <version>2.2.9</version>
</dependency>

任何优雅的解决方案?

更新

根据senia的回答,这解决了这个问题:

def toParameterValueSet(seq: Seq[Any]) = seq.map(v => v: anorm.ParameterValue[_])
val row = Seq(5, "name5")
SQL("insert into emp (id, name) values ({id}, {name})").onParams(toParameterValue(row):_*).executeUpdate()

有没有办法消除声明/使用toParameterValueSet的需要?

(例如,告诉scala在自动扩展:_*上使用隐式转换)

更新

更紧凑:

implicit def toParameterValueSet(seq: Seq[Any]): Seq[anorm.ParameterValue[_]] = seq.map(v => v: anorm.ParameterValue[_])
val row = Seq(5, "name5")
SQL("insert into emp (id, name) values ({id}, {name})").onParams(row:_*).executeUpdate()

@Typesafe团队:您可以在acrom SQL上添加一个参数来获取一系列值吗? (而不必使用:_ *) (我同意使用命名参数是首选,但有时使用未命名的参数仍然有用)

2 个答案:

答案 0 :(得分:3)

您可以尝试替换

val row = Seq(4, "name4")

val row = Seq[anorm.ParameterValue[_]](4, "name4")

所有类型都有隐式转换,因此您可以使用row.map{ e => e: anorm.ParameterValue[_] }

转换集合

答案 1 :(得分:2)

只需指定type即可。 <:定义了类型绑定。

A <: B

表示A必须由B类绑定,或者任何A是B的子类型。给row:_*一个正确的type绑定。我认为String有效。 anorm.ParameterValue[String]

更具体地说,val row = Seq[anorm.ParameterValue[_]](4, "name4")。这应该执行implicit转换。