为什么光滑表中的列是 defs 而不是 vals?
Why columns in slick Tables are defs instead of vals?
In slick documentation table 中的列定义为 def
class Coffees(tag: Tag) extends Table[(String, Int, Double, Int, Int)](tag, "COFFEES") {
def name = column[String]("COF_NAME", O.PrimaryKey)
def supID = column[Int]("SUP_ID")
def price = column[Double]("PRICE")
def sales = column[Int]("SALES", O.Default(0))
def total = column[Int]("TOTAL", O.Default(0))
def * = (name, supID, price, sales, total)
}
有没有理由不应该是这样的:
class Coffees(tag: Tag) extends Table[(String, Int, Double, Int, Int)](tag, "COFFEES") {
val name = column[String]("COF_NAME", O.PrimaryKey)
val supID = column[Int]("SUP_ID")
val price = column[Double]("PRICE")
val sales = column[Int]("SALES", O.Default(0))
val total = column[Int]("TOTAL", O.Default(0))
val * = (name, supID, price, sales, total)
}
列似乎没有使用任何可以改变的东西。
简答:
初始化顺序。
长答案:
让我们收集一些事实:
1) 使用 val
s 而不是 def
s 大多数情况下是可行的(如果您在代码中将大部分 def
s 更改为 val
s 它将大部分时间表现正确 - 至少这对我来说是这样)
2) 大多数 Slick
代码示例使用 def
s.
因此,如果发生错误,可能只会在某些(罕见的?)情况下发生。
Slick
本身的这部分代码可能会阐明一些信息(查看 if(tt == null)
(class `RelationalProfile):
之后的注释
def column[C](n: String, options: ColumnOption[C]*)(implicit tt: TypedType[C]): Rep[C] = {
if(tt == null) throw new NullPointerException(
"implicit TypedType[C] for column[C] is null. "+
"This may be an initialization order problem. "+
"When using a MappedColumnType, you may want to change it from a val to a lazy val or def.")
new Rep.TypedRep[C] {
override def toNode =
Select((tableTag match {
case r: RefTag => r.path
case _ => tableNode
}), FieldSymbol(n)(options, tt)) :@ tt
override def toString = (tableTag match {
case r: RefTag => "(" + _tableName + " " + r.path + ")"
case _ => _tableName
}) + "." + n
}
}
如果您查看引入此更改的提交:https://github.com/slick/slick/commit/be2ff6513d46abc9a25c8752c2931a786d4c5ad6
你应该找到很好的解释(提交评论)。
In slick documentation table 中的列定义为 def
class Coffees(tag: Tag) extends Table[(String, Int, Double, Int, Int)](tag, "COFFEES") {
def name = column[String]("COF_NAME", O.PrimaryKey)
def supID = column[Int]("SUP_ID")
def price = column[Double]("PRICE")
def sales = column[Int]("SALES", O.Default(0))
def total = column[Int]("TOTAL", O.Default(0))
def * = (name, supID, price, sales, total)
}
有没有理由不应该是这样的:
class Coffees(tag: Tag) extends Table[(String, Int, Double, Int, Int)](tag, "COFFEES") {
val name = column[String]("COF_NAME", O.PrimaryKey)
val supID = column[Int]("SUP_ID")
val price = column[Double]("PRICE")
val sales = column[Int]("SALES", O.Default(0))
val total = column[Int]("TOTAL", O.Default(0))
val * = (name, supID, price, sales, total)
}
列似乎没有使用任何可以改变的东西。
简答: 初始化顺序。
长答案:
让我们收集一些事实:
1) 使用 val
s 而不是 def
s 大多数情况下是可行的(如果您在代码中将大部分 def
s 更改为 val
s 它将大部分时间表现正确 - 至少这对我来说是这样)
2) 大多数 Slick
代码示例使用 def
s.
因此,如果发生错误,可能只会在某些(罕见的?)情况下发生。
Slick
本身的这部分代码可能会阐明一些信息(查看 if(tt == null)
(class `RelationalProfile):
def column[C](n: String, options: ColumnOption[C]*)(implicit tt: TypedType[C]): Rep[C] = {
if(tt == null) throw new NullPointerException(
"implicit TypedType[C] for column[C] is null. "+
"This may be an initialization order problem. "+
"When using a MappedColumnType, you may want to change it from a val to a lazy val or def.")
new Rep.TypedRep[C] {
override def toNode =
Select((tableTag match {
case r: RefTag => r.path
case _ => tableNode
}), FieldSymbol(n)(options, tt)) :@ tt
override def toString = (tableTag match {
case r: RefTag => "(" + _tableName + " " + r.path + ")"
case _ => _tableName
}) + "." + n
}
}
如果您查看引入此更改的提交:https://github.com/slick/slick/commit/be2ff6513d46abc9a25c8752c2931a786d4c5ad6
你应该找到很好的解释(提交评论)。