简体   繁体   English

Scala这个“_1”的类型是什么?

[英]Scala What is this “_1” in type?

I would like to understand this error: 我想了解这个错误:

found   : row.type (with underlying type _#TableElementType)
required: _1#TableElementType

Looks like I was very close, but what is this "1" in _1#TableElementType ? 看起来我非常接近,但_1#TableElementType这个“1”是什么? Can I convert one in the other? 我可以在另一个中转换一个吗?

Edit : useful bits of codes for context (Play + Slick): 编辑 :上下文的有用代码位(Play + Slick):

abstract class GenericDAO[T <: AbstractTable[_]](...) {
  def table: TableQuery[T]
  def insert(model: T#TableElementType) = db run (table += model)
}

trait TableObject[T <: AbstractTable[_]] {
  def rowFromJson(jsObject: JsObject): T#TableElementType
  def dao(driver: JdbcProfile, db: Database): GenericDAO[T]
}

// Controller Action with an instance implementing `tableObject` above:
val tableObject = tableObjectFactory("test")
val row = tableObject.rowFromJson(request.body.asJson.get)
val dao = tableObject.dao(driver, db)  // tableObject has a DOA extending GenericDAO
dao.insert(row)

Example of tableObject : tableObject示例:

object TestTable extends TableObject[Test] {
  def dao(driver: JdbcProfile, db: Database) = new TestDAO(driver, db)
  def rowFromJson(j: JsObject): TestRow = { TestRow(...) }
  class TestDAO(...) extends GenericDAO[Test](driver, db) { ... }
}

I use a factory to get the right one from the url: 我使用工厂从网址获取正确的工厂:

object TableObjectFactory {
  def tableObjectFactory(name: String) = {
    name match {
      case "test" => TestTable
      case "projects" => ProjectsTable
      case "people" => PeopleTable
      ...
    }
  }
}

Although it doesn't explain much, it works if I make the DAO parse the request body and insert, instead of producing the row object separately and applying one of the DAO's methods on it. 虽然它没有解释得太多,但是如果我让DAO解析请求体并插入,而不是单独生成行对象并在其上应用DAO的方法之一,它就有效。

I got all kinds of similar errors with names such as _$1#TableElementType , _1$u#TableElementType etc., but I think they are compiler aliases for different instances of the same class. 我有各种类似的错误,例如_$1#TableElementType_1$u#TableElementType等,但我认为它们是同一类的不同实例的编译器别名。

So the solution was to do 所以解决方案就是这样做

val j: JsValue = request.body.asJson.get
val tableObject: TableObject[_] = tableObjectFactory(table)
val dao = tableObject.dao(driver, db)
val res: Future[Int] = dao.insert(j)

where this new insert method now is abstract in GenericDAO , and in the concrete implementations takes a JsValue and parses it, then inserts: 这个新的insert方法现在在GenericDAO抽象的,并且在具体实现中采用JsValue并解析它,然后插入:

class TestDAO(override val driver: JdbcProfile, override val db: Database) extends GenericDAO[Test](driver, db) {
  import this.driver.api._

  val table = TableQuery[Test]

  //def insert(model: TestRow) = db run (table += model)   // NO!

  def insert(j: JsValue): Future[Int] = {
    val row = TestRow(
      (j \ "id").as[Int],
      (j \ "name").as[String],
      (j \ "value").as[Float],
      (j \ "other").as[String]
    )
    db run (table += row)
  }
}

At the same time, it makes Play forms completely useless, which is a good thing anyway. 同时,它使Play表格完全无用,无论如何这都是一件好事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM