当重载`apply`方法时:光滑的错误消息'值tupled不是对象的成员'

时间:2016-12-16 07:45:26

标签: scala slick

我需要能够通过在某些情况下提供除User之外的所有值来创建id对象,以便User对象负责为自己分配一个自动生成的值

为此我在配对对象中重载了apply方法,如下所示。但这导致编译时错误:value tupled is not a member of object

StackOverflow和其他博客上提到的解决方案并不起作用,例如: http://queirozf.com/entries/slick-error-message-value-tupled-is-not-a-member-of-object

case class User(id: Long, firstName: String, lastName: String, mobile: Long, email: String)

object User {
  private val seq = new AtomicLong

  def apply(firstName: String, lastName: String, mobile: Long, email: String): User = {
    User(seq.incrementAndGet(), firstName, lastName, mobile, email)
  }
}

class UserTableDef(tag: Tag) extends Table[User](tag, "user") {

  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def firstName = column[String]("first_name")
  def lastName = column[String]("last_name")
  def mobile = column[Long]("mobile")
  def email = column[String]("email")

  override def * =
    (id, firstName, lastName, mobile, email) <> (User.tupled, User.unapply)

}

3 个答案:

答案 0 :(得分:5)

问题的根源是重载apply def。

tupled不适用于case classless than 2 parameters {/ 1}}。

就光滑的overloaded apply(或全部)映射和*而言,它应该是,

<>

这样,

  • def * = (tupleMember1, tupleMember2, ...) <> (func1, func2) 将该元组func1作为输入并返回映射的类/案例类的实例。
  • (tupleMember1, tupleMember2, ...)获取映射的类/ case类的实例并返回该元组func1

因此,您可以提供满足这些要求的任何功能。

(tupleMember1, tupleMember2, ...)

答案 1 :(得分:0)

  

注意:使用内部原子长度可能是一个坏主意   id生成器而不是使用自动增量序列生成器   数据库提供,因为它们可以安全地防止并发访问   多个应用程序。

现在回到代码,在函数上定义 tupled 方法,并将具有 N个参数的函数转换为具有单个论证, N-arity的元组

从您的描述中看,重载apply方法会导致编译器无法确定哪个&#34;应用&#34;应该选择实施。所以你应该做两件事:

  1. 重命名第二个申请(一般情况下,请避免超载)
  2. 明确调用tupled(即User.withEmptyId.tupled)

答案 2 :(得分:0)

一种可能的解决方案是将secondary constructor推送到case class定义本身,然后使用问题中指定的博客文章中提到的工作。

然后,您可以创建User个对象而不指定id,但是,您可能仍需要使用new关键字,例如new User(firstName, lastName, mobile, email)

case class User(id: Long, firstName: String, lastName: String, mobile: Long, email: String) {

  def this(firstName: String, lastName: String, mobile: Long, email: String) =
    this(User.seq.incrementAndGet(), firstName, lastName, mobile, email)
}

object User {
  private val seq = new AtomicLong
}

class UserTableDef(tag: Tag) extends Table[User](tag, "user") {

  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def firstName = column[String]("first_name")
  def lastName = column[String]("last_name")
  def mobile = column[Long]("mobile")
  def email = column[String]("email")

  override def * =
    (id, firstName, lastName, mobile, email) <> ((User.apply _).tupled, User.unapply)

}