Расширенные методы в оболочке класса логических значений

В моей кодовой базе я использовал теги для кодирования некоторой информации в типы. Как работает тэги используя 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

Другие вопросы по тегам