ScalaQuery 中理解的元素类型

发布于 2024-10-27 08:02:32 字数 1618 浏览 1 评论 0原文

当我学习 ScalaQuery 的查询教程时,我发现了一些有趣的东西,但我不太清楚为什么。

这是我定义的数据库架构:

object Users extends Table[(Int, String, String)]("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 
}

这是我使用的查询:

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
        }
    }
}

在本例中,您可以看到在 query1query2 中都使用了类似 user.data 的内容。 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)

看起来 println 语句中的 user 是 Tuple3 的类型。如果我像下面的普通元组一样使用 user ,它就会起作用。

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

你可以看到,在for表达式的保护中我仍然使用user.id,那么user的类型是什么?为什么我可以在guard和yield块中使用user.id,但我需要将它用作for表达式主体中的元组?

谢谢。

I'm found something interesting when I following the Queries tutorial of ScalaQuery that I don't know why quite well.

Here is my database schema defined:

object Users extends Table[(Int, String, String)]("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 
}

And here is the query I use:

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
        }
    }
}

In this case, you could see that in both query1 and query2 use something like user.id, it seems that user is type of singleton object Users which I just defined above. So it has all methods defined on that object.

But if I try to run the query directly without yield keyword, for example:

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

In this case, the compiler complain:

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

It seems like user in the println statement is type of Tuple3. And if I use user like ordinary tuple like the following, it will work.

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

And you could see, in the guard of for expression I still use user.id, so what is the type of user? Why I could use user.id in the guard and yield block, but I need use it as a tuple in the body of for expression?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

回心转意 2024-11-03 08:02:32

在第一个代码片段中:

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

userobject Users,因为查询的map方法定义为def map[F](f: E => F): Query[F],第一个代码段是 equals:

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

因此 EUsers 的类型,而 Users 实例是参数赋予f(E):F

如果你想将行作为对象访问,你需要定义用户如下:

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
}

In the first code snippet:

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

user is object Users because the Query's map method is defined as def map[F](f: E => F): Query[F], the first code snippet is equals:

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

so the E is Users's type and Users instance is the parameter give to f(E):F.

If you want to visit row as a Object, you need define Users as below:

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)

and then

for (user <- Users if user.id > 5) {
  println ("UserID:" + user.id)  // user is a User instance
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文