Для тела понимания, чтобы выполнить, когда Lift Box [T] имеет пустое значение - PullRequest
1 голос
/ 12 февраля 2012

Я очень доволен работой с типом Option в Scala, и Lift's Box[T] тоже великолепен.

Но меня немного смущает, как обращаться с Empty, когда оно действительно.

Например, моя программа имеет три значения: title, startDate и endDate, title и startDate обязательные для заполнения поля, но endDate может быть пустым.

Теперь я хочу получить эти данные из базы данных, поэтому я обернул их в Box[T], и в следующем случае endDate вернул Empty, что означает, что в базе данных это NULL.

Теперь я хочу напечатать эти данные на экране, поэтому у меня есть следующий код, но он не будет работать, потому что endDate пусто, поэтому тело для понимания не будет выполнено.

import net.liftweb.common._

object Main
{
    val title: Box[String] = Full("title")
    val startDate: Box[String] = Full("startDate")
    val endDate: Box[String] = Empty

    def main(args: Array[String]) {

        for (title <- this.title; startDate <- this.startDate; 
             endDate <- this.endDate)  
        {   
            println("Title:" + title)
            println("StartDate:" + startDate)
            println("EndDate:" + endDate)   // I hope now endDate = Empty or None
        }
    }
}

Если я сделаю endDate как Box[Option[String]], он будет работать нормально, но я чувствую, что это немного некрасиво, потому что Box[String] должно быть достаточно, чтобы обозначить, что endDate равно NULL в базе данных.

Ответы [ 2 ]

1 голос
/ 13 февраля 2012

Если вы хотите обработать случай, когда endDate равен Empty, просто не извлекайте его.

for (title <- this.title; startDate <- this.startDate) {
  println("Title:" + title)
  println("StartDate:" + startDate)
  println("EndDate:" + this.endDate)   // this.endDate == Empty
}

Редактировать

Если вы обрабатываете сбои, просто добавьте match..case или if тесты.

this.endDate match {
  case f: Failure =>
    // handle failure
  case endDate =>
    for (title <- this.title; startDate <- this.startDate) {
      println("Title:" + title)
      println("StartDate:" + startDate)
      println("EndDate:" + endDate)   // endDate == Empty
    }
}
1 голос
/ 12 февраля 2012

Наконец, я выступаю с этим неявным классом преобразования и оболочки:

class ValidEmptyBox[T](box: Box[T])
{
    def validEmpty: Box[Box[T]] = box match {
        case Full(x) => Full(Full(x))
        case Empty => Full(Empty)
        case Failure(msg, exception, chain) => Failure(msg, exception, chain)
    }
}

object ValidEmptyBox {
    implicit def toValidEmptyBox[T](box: Box[T]) = new ValidEmptyBox(box)
}

for(empty <- Empty.validEmpty) {
    println(empty) // Empty
}

for(full <- Full("AA").validEmpty) {
    println(full)  // Full(AA)
}

for(fail <- Failure("Failure").validEmpty) {
    println(fail)  // No output
}

Кажется, это работает для меня, но я все же хотел бы знать, есть ли лучший способ сделать это.

...