如何覆盖 case class 属性并避免重复存储?
How to override a case class attribute and avoid duplicated storage?
我有一个用例可以利用 case class 属性覆盖,如果这在 Scala 2 中可行的话。12.x。我的用例如下: Play-Silhouette (P-S) 中有多个案例 classes LoginInfo
图书馆建立在:
case class LoginInfo(providerID: String, providerKey: String)
如果生活是完美的,这些将是特征而不是大小写 classes 但是好吧,现在在一个重新使用 P-S 的项目中我想设计我的数据库,自定义 Slick 代码生成器并为那些 P-S 案例获取 Slick-mapped 数据库友好定义 classes 例如
case class LoginInfoRow(id: Int, override val providerID: String, override val providerKey: String, modified: Option[java.sql.Timestamp] = None)
extends com.mohiva.play.silhouette.api.LoginInfo(providerID, providerKey)
这种方法可以让我将我的 Slick-persistence 专业 LoginInfoRow
无缝地插入到 P-S 框架中。请注意,这是使用 Slick + 我的自定义生成器更改从数据库自动生成的。上面的 LoginInfoRow
定义导致编译错误:
[error] /home/skywalker/code/play-silhouette-seed/app/models/generated/Tables.scala:29:14: case class LoginInfoRow has case ancestor com.mohiva.play.silhouette.api.LoginInfo, but case-to-case inheritance is prohibited. To overcome this limitation, use extractors to pattern match on non-leaf nodes.
[error] case class LoginInfoRow(id: Int, override val providerID: String, override val providerKey: String, modified: Option[java.sql.Timestamp] = None) extends com.mohiva.play.silhouette.api.LoginInfo(providerID, providerKey)
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 3 s, completed May 25, 2019 12:06:43 PM
一个可能的解决方案是为这两个属性使用不同的名称,但是从 LoginInfoRow
的界面来看,使用哪个属性会让人感到困惑?而且它还会重复存储。
此编译器建议的替代方案是什么 To overcome this limitation, use extractors to pattern match on non-leaf nodes.
?
您可以为这种情况编写隐式或显式转换器。
隐式转换器:
implicit def loginInfoRowToLoginInfo(loginInfoRow: LoginInfoRow): LoginInfo = {
LoginInfo(loginInfoRow.providerID, loginInfoRow.providerKey)
}
显式转换器:
case class LoginInfoRow(
id: Int,
providerID: String,
providerKey: String,
modified: Option[java.sql.Timestamp] = None
) {
def toSilhouette: LoginInfo = {
LoginInfo(providerID, providerKey)
}
}
或两者兼而有之。
我有一个用例可以利用 case class 属性覆盖,如果这在 Scala 2 中可行的话。12.x。我的用例如下: Play-Silhouette (P-S) 中有多个案例 classes LoginInfo
图书馆建立在:
case class LoginInfo(providerID: String, providerKey: String)
如果生活是完美的,这些将是特征而不是大小写 classes 但是好吧,现在在一个重新使用 P-S 的项目中我想设计我的数据库,自定义 Slick 代码生成器并为那些 P-S 案例获取 Slick-mapped 数据库友好定义 classes 例如
case class LoginInfoRow(id: Int, override val providerID: String, override val providerKey: String, modified: Option[java.sql.Timestamp] = None)
extends com.mohiva.play.silhouette.api.LoginInfo(providerID, providerKey)
这种方法可以让我将我的 Slick-persistence 专业 LoginInfoRow
无缝地插入到 P-S 框架中。请注意,这是使用 Slick + 我的自定义生成器更改从数据库自动生成的。上面的 LoginInfoRow
定义导致编译错误:
[error] /home/skywalker/code/play-silhouette-seed/app/models/generated/Tables.scala:29:14: case class LoginInfoRow has case ancestor com.mohiva.play.silhouette.api.LoginInfo, but case-to-case inheritance is prohibited. To overcome this limitation, use extractors to pattern match on non-leaf nodes.
[error] case class LoginInfoRow(id: Int, override val providerID: String, override val providerKey: String, modified: Option[java.sql.Timestamp] = None) extends com.mohiva.play.silhouette.api.LoginInfo(providerID, providerKey)
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 3 s, completed May 25, 2019 12:06:43 PM
一个可能的解决方案是为这两个属性使用不同的名称,但是从 LoginInfoRow
的界面来看,使用哪个属性会让人感到困惑?而且它还会重复存储。
此编译器建议的替代方案是什么 To overcome this limitation, use extractors to pattern match on non-leaf nodes.
?
您可以为这种情况编写隐式或显式转换器。
隐式转换器:
implicit def loginInfoRowToLoginInfo(loginInfoRow: LoginInfoRow): LoginInfo = {
LoginInfo(loginInfoRow.providerID, loginInfoRow.providerKey)
}
显式转换器:
case class LoginInfoRow(
id: Int,
providerID: String,
providerKey: String,
modified: Option[java.sql.Timestamp] = None
) {
def toSilhouette: LoginInfo = {
LoginInfo(providerID, providerKey)
}
}
或两者兼而有之。