为什么光滑表中的列是defs而不是vals?

时间:2016-12-14 20:30:30

标签: scala slick

表中的slick documentation列中定义了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 个答案:

答案 0 :(得分:3)

简短回答: 初始化顺序。

答案很长:

让我们收集一些事实:

1)使用val代替def s主要有效(如果您在代码中将大部分def更改为val s,那么大部分时间行为正确 - 至少这是我的工作方式)

2)Slick代码的大多数示例都使用def s。

因此,如果出现错误,可能只会发生在某些(罕见?)案件中。

Slick本身的代码中可能会有一些亮点(看看if(tt == null)之后的注释(类`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

你应该找到很好的解释(提交评论)。