簡體   English   中英

為什么scala:_ *將Seq擴展為可變長度參數列表在這種情況下不起作用?

[英]Why the scala :_* to expand a Seq into variable-length argument list does not work in this case?

為什么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上添加一個參數來獲取一系列值? (而不是必須使用:_ *)(我同意使用命名參數是首選,但有時使用未命名參數仍然有用)

你可以試着替換

val row = Seq(4, "name4")

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

所有類型都有隱式轉換,因此您可以使用row.map{ e => e: anorm.ParameterValue[_] }轉換集合row.map{ e => e: anorm.ParameterValue[_] }

只需指定type <:定義類型綁定。

A <: B

說A必須用B類綁定,或者任何A是B的子類型。給那row:_*一個正確的type綁定。 我認為String界限有效。 anorm.ParameterValue[String]

更具體地說, val row = Seq[anorm.ParameterValue[_]](4, "name4") 這應該執行implicit轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM