Тип элементов для понимания в ScalaQuery - PullRequest
2 голосов
/ 28 марта 2011

Я обнаружил кое-что интересное, когда я следую учебному пособию по запросам ScalaQuery, которое я не очень хорошо понимаю, почему.

Вот моя схема базы данных, определенная:вот запрос, который я использую:

object Main
{
    val database = Database.forURL("jdbc:sqlite:sample.db", driver = "org.sqlite.JDBC")
    def main(args: Array[String]) {
        database withSession {

            val query1 = for (user <- Query(Users)) yield user.id ~ user.last
            val query2 = for (user <- Users if user.id > 5) yield user.id ~ user ~ last
        }
    }
}

В этом случае вы могли видеть, что и в query1, и в query2 используется что-то вроде user.id, кажется, что user является типом синглтонаobject Users, который я только что определил выше.Таким образом, для этого объекта определены все методы.

Но если я попытаюсь выполнить запрос напрямую без ключевого слова yield, например:

for (user <- Users if user.id > 5) {
    println ("UserID:" + user.id)
}

В этом случае компилятор жалуется:

[error] src/main/scala/Test.scala:23: value id is not a member of (Int, String, String)
[error]    println ("UserID:" + user.id)

Кажется, что user в выражении println является типом Tuple3.И если я использую user как обычный кортеж, подобный следующему, он будет работать.

for (user <- Users if user.id > 5) {
    println ("UserID:" + user._1)
}

И вы можете видеть, что в выражении для выражения я все еще использую user.id, так что типuser?Почему я мог использовать user.id в блоке guard и yield, но мне нужно использовать его как кортеж в теле выражения?

Спасибо.

1 Ответ

7 голосов
/ 28 марта 2011

В первом фрагменте кода:

val query1 = for (user <- Query(Users)) yield user.id ~ user.last

user равно object Users, поскольку метод карты запроса определен как def map[F](f: E => F): Query[F], первый фрагмент кода равен:

Query(Users).map(user => user.id ~ user.last)

так что E - это тип Users, а Users - это параметр, который присваивается f(E):F.

Если вы хотите просмотреть строку как Объект, вам нужно определить Users какниже:

import org.scalaquery.ql.basic.{BasicTable => Table}
object Users extends Table[User]("users") {
  def id = column[Int]("id", O NotNull)
  def first = column[String]("first", O NotNull)
  def last = column[String]("last", O NotNull)
  def * = id ~ first ~ last <> (User, User.unapply _)
}

case class User(id: Int, first: String, last: String)

, а затем

for (user <- Users if user.id > 5) {
  println ("UserID:" + user.id)  // user is a User instance
}
...