ScalaQuery 中理解的元素类型
当我学习 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
}
}
}
在本例中,您可以看到在 query1
和 query2
中都使用了类似 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在第一个代码片段中:
user
是object Users
,因为查询的map方法定义为def map[F](f: E => F): Query[F]
,第一个代码段是 equals:因此
E
是Users
的类型,而Users
实例是参数赋予f(E):F
。如果你想将行作为对象访问,你需要定义用户如下:
然后
In the first code snippet:
user
isobject Users
because the Query's map method is defined asdef map[F](f: E => F): Query[F]
, the first code snippet is equals:so the
E
isUsers
's type andUsers
instance is the parameter give tof(E):F
.If you want to visit row as a Object, you need define Users as below:
and then