Расширенные методы в оболочке класса логических значений
В моей кодовой базе я использовал теги для кодирования некоторой информации в типы. Как работает тэги используя t.asInstanceOf[T @@ U]
Я мог бы избежать многих проблем с записью отображения между упакованными и развернутыми значениями.
Недавно я ударил по стене теговыми типами, поскольку они нарушают некоторую функциональность в бесформенной форме, которую я хотел бы использовать, поэтому я пытаюсь использовать классы значений.
До сих пор я мог обманывать некоторые, например, логические проверки с теговыми типами, используя что-то вроде:
implicit class TaggedBooleanAsFirstOperand[P1, U](val c: Rep[P1 @@ U]) {
private val em = new BooleanColumnExtensionMethods[P1](c.asInstanceOf[Rep[P1]])
type o = OptionMapperDSL.arg[Boolean, P1]
def @&&[P2, R](b: Rep[P2])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.&&[P2, R](b)
def @||[P2, R](b: Rep[P2])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.||[P2, R](b)
def unary_! : Rep[P1] = em.unary_!
}
implicit class TaggedBooleanAsSecondOperand[P1](val c: Rep[P1]) {
private val em = new BooleanColumnExtensionMethods[P1](c)
type o = OptionMapperDSL.arg[Boolean, P1]
def &&@[P2, U, R](b: Rep[P2 @@ U])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.&&[P2, R](b.asInstanceOf[Rep[P2]])
def ||@[P2, U, R](b: Rep[P2 @@ U])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.||[P2, R](b.asInstanceOf[Rep[P2]])
}
implicit class TaggedBooleanAsBothOperands[P1, U](val c: Rep[P1 @@ U]) {
private val em = new BooleanColumnExtensionMethods[P1](c.asInstanceOf[Rep[P1]])
type o = OptionMapperDSL.arg[Boolean, P1]
def @&&@[P2, V, R](b: Rep[P2 @@ V])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.&&[P2, R](b.asInstanceOf[Rep[P2]])
def @||@[P2, V, R](b: Rep[P2 @@ V])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.||[P2, R](b.asInstanceOf[Rep[P2]])
}
С AnyVal
тем не менее, я не могу просто привести один тип к другому, где я хочу, и мне пришлось бы предоставить какой-то честный код, позволяющий достичь того, чего я хочу.
Я пытался прочитать исходный код Slick, но сама идея, с которой мне следует начать, немного размыта для меня - релевантная информация разбросана по многим местам, поэтому я не могу просто указать несколько мест, например, чтобы понять, как их сопоставить. Rep
в другой или извлекать данные из булевых обернутых и развернутых и объединить их.
Могут ли некоторые эксперты Slick порекомендовать для них хорошую отправную точку?
1 ответ
Теги на самом деле дают вам не только безопасность типов. Это также дает вам уровень абстракции. Как только вы завернули boolean
в tag
Вы абстрагируетесь от представления времени выполнения вашего логического значения. Кстати, вы должны использовать Tag.unwrap
или же Tag.unsubst
вместо asInstanceOf
, Слик работает на более низком уровне абстракции. Он работает с простыми типами, о которых знает SQL. Конечно надо unwrap
теги где-то посередине, прежде чем работать с БД. Я бы включил это в схему таблицы. См. Раздел "Сопоставленные таблицы": http://slick.lightbend.com/doc/3.0.0/schemas.html