处理枚举类型的通用映射函数
Generic mapping function to handle enumeration types
我有以下枚举类型。
class Payment extends Enumeration {
type Payment = Value
val Cash, CreditCard, Unspecified = Value
}
object Payment extends Payment
class Ticket extends Enumeration {
type Ticket = Value
val Normal, Discount, Other = Value
}
object Ticket extends Ticket
我将枚举声明为 类 而不是对象,因为我稍后需要类型信息(对于 MappedColumnType)。
这是 slick 的非工作版本 table:
class Stats(tag: Tag) extends Table[Stat](tag, "STATS") {
implicit def enumToInt[E <: Enumeration : ClassTag, V : ClassTag](implicit conv: V => E#Value): BaseColumnType[V] =
MappedColumnType.base[V, Int] (
value => value.id,
num => implicitly[ClassTag[E]].runtimeClass.newInstance().asInstanceOf[E](num).asInstanceOf[V]
)
def entityid = column[Int]("ENTITYID")
def email = column[String]("EMAIL")
def payment = column[Payment]("PAYMENT")
def ticket = column[Ticket]("TICKET")
def phone = column[String]("PHONE")
def ticket_source = column[TicketSource]("TICKETSOURCE")
def * = (entityid, email, payment, ticket, phone, ticket_source) <>
(Stat.tupled, Stat.unapply)
}
我的目标是定义一个通用映射器函数来处理所有枚举,因为转换方法对所有类型的枚举都有效(值到 id,id 到值)。
在映射器函数中,我尝试捕获 ClassTag 信息并创建一个 运行 实例来调用 returns 枚举 Value
的应用方法。我必须将 .asinstanceOf[V]
添加到 apply
方法的结果中,否则会出现关于 E#Value
与 V
的预期值不匹配的错误。
现在,这是我收到的错误消息:
Tables.scala:45: could not find implicit value for parameter tm: scala.slick.ast.TypedType[com.yokyer.tiyatrosever.models.Payment]
[error] def payment = column[Payment]("PAYMENT")
[error] ^
Tables.scala:46: could not find implicit value for parameter tm: scala.slick.ast.TypedType[com.yokyer.tiyatrosever.models.Ticket]
[error] def ticket = column[Ticket]("TICKET")
我是 scala 的新手,我把一堆关于反射的食谱放在一起,想知道我是否做错了根本性的事情。
您需要创建一个 MappedColumnType
import profile.simple._
def enumValueMapper(enum: Enumeration) = MappedColumnType.base[enum.Value, String](
e => e.toString,
s => Try(enum.withName(s)).getOrElse(throw new IllegalArgumentException
(s"enumeration $s doesn't exist $enum
[${enum.values.mkString(",")}]"))
)
def enumIdMapper(enum: Enumeration) = MappedColumnType.base[enum.Value, Int](
e => e.id,
i => enum.apply(i)
)
那么你可以使用
// It convert Enum to Int
implicit val paymentMapper = enumIdMapper(Payment)
或者
// It convert Enum to String
implicit val paymentMapper = enumValueMapper(Payment)
我有以下枚举类型。
class Payment extends Enumeration {
type Payment = Value
val Cash, CreditCard, Unspecified = Value
}
object Payment extends Payment
class Ticket extends Enumeration {
type Ticket = Value
val Normal, Discount, Other = Value
}
object Ticket extends Ticket
我将枚举声明为 类 而不是对象,因为我稍后需要类型信息(对于 MappedColumnType)。
这是 slick 的非工作版本 table:
class Stats(tag: Tag) extends Table[Stat](tag, "STATS") {
implicit def enumToInt[E <: Enumeration : ClassTag, V : ClassTag](implicit conv: V => E#Value): BaseColumnType[V] =
MappedColumnType.base[V, Int] (
value => value.id,
num => implicitly[ClassTag[E]].runtimeClass.newInstance().asInstanceOf[E](num).asInstanceOf[V]
)
def entityid = column[Int]("ENTITYID")
def email = column[String]("EMAIL")
def payment = column[Payment]("PAYMENT")
def ticket = column[Ticket]("TICKET")
def phone = column[String]("PHONE")
def ticket_source = column[TicketSource]("TICKETSOURCE")
def * = (entityid, email, payment, ticket, phone, ticket_source) <>
(Stat.tupled, Stat.unapply)
}
我的目标是定义一个通用映射器函数来处理所有枚举,因为转换方法对所有类型的枚举都有效(值到 id,id 到值)。
在映射器函数中,我尝试捕获 ClassTag 信息并创建一个 运行 实例来调用 returns 枚举 Value
的应用方法。我必须将 .asinstanceOf[V]
添加到 apply
方法的结果中,否则会出现关于 E#Value
与 V
的预期值不匹配的错误。
现在,这是我收到的错误消息:
Tables.scala:45: could not find implicit value for parameter tm: scala.slick.ast.TypedType[com.yokyer.tiyatrosever.models.Payment]
[error] def payment = column[Payment]("PAYMENT")
[error] ^
Tables.scala:46: could not find implicit value for parameter tm: scala.slick.ast.TypedType[com.yokyer.tiyatrosever.models.Ticket]
[error] def ticket = column[Ticket]("TICKET")
我是 scala 的新手,我把一堆关于反射的食谱放在一起,想知道我是否做错了根本性的事情。
您需要创建一个 MappedColumnType
import profile.simple._
def enumValueMapper(enum: Enumeration) = MappedColumnType.base[enum.Value, String](
e => e.toString,
s => Try(enum.withName(s)).getOrElse(throw new IllegalArgumentException
(s"enumeration $s doesn't exist $enum
[${enum.values.mkString(",")}]"))
)
def enumIdMapper(enum: Enumeration) = MappedColumnType.base[enum.Value, Int](
e => e.id,
i => enum.apply(i)
)
那么你可以使用
// It convert Enum to Int
implicit val paymentMapper = enumIdMapper(Payment)
或者
// It convert Enum to String
implicit val paymentMapper = enumValueMapper(Payment)