Scala条件无值赋值

时间:2017-02-19 09:51:00

标签: scala

我正在尝试将com.google.gson.JsonObject转换为case类对象。有时记录中的某些元素缺失,在这种情况下,我希望将它指定为案例类成员

object tmp {
  case class person(name: String, age: Long)
  def main(args: Array[String]): Unit = {
   val parser = new JsonParser();

   //PERSON 2
   val record2 = parser.parse("""{"name":"xyz"}""").getAsJsonObject()

   val record2_name = record2.get("name").getAsString.toLowerCase
   val record2_age = if(record2.get("age") != null) record2.get("age") else None

   val person2 = new person(record2_name,record2_age)  //-> Type Mismatch, expected: Long, actual: Long

   println(person2);

  }
}

2 个答案:

答案 0 :(得分:1)

您根本无法使用不同类型age: Long的参数调用一种类型的参数Option[Long]

至少这是你的问题所暗示的。

您需要定义可能缺少的属性Option

e.g。在你的例子中

case class person(name: String, age: Option[Long])

然后当你提取json值时,你可以使用Option.apply方法,如果参数为None

,则返回null
…
val record2_age = Option(record2.get("age")).map(_.getAsLong) // None if get("age) returns null
…
val person2 = new person(record2_name,record2_age)  //There should be no more type mismatch now

答案 1 :(得分:0)

在您的情况下,public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { return $request->user($guard)->is_admin ? redirect('/admin') : redirect('/home'); } return $next($request); } 类型为record2_age,类型为java JsonElement,但由于您为其分配Object,因此None变为Any您尝试分配给Long类型的。

简短的回答是,

val person = new person(jsonObject.get("name").getAsString.toLowerCase,
    Option(jsonObject.get("age")).map(_.getAsLong).getOrElse(0l))

这种方式如果jsonObject.get("age")为空,Option(null)会为您提供None,或者如果有Option(28) = Some(28)

如果空的话,您可能希望自己的年龄为0l。如果您希望它为None,则可以使用Option[Long]

1)更简单的方式

class GsonCaseClassSpecs extends FunSpec {

  describe("case class conversion") {

    it("converts gson with name/age to case class") {

      case class person(name: String, age: Long)

      val parser = new JsonParser()

      //case 1
      val jsonObject : JsonObject = parser.parse("""{"name":"xyz"}""").getAsJsonObject

      val age = jsonObject.get("age") match {
        case null => None
        case value => Some(value.getAsLong)
      }

      val person1 = new person(jsonObject.get("name").getAsString.toLowerCase, age.getOrElse(0l))

      assert(person1.name == "xyz")
      assert(person1.age == 0)

      //case 2
      val jsonObject2 : JsonObject = parser.parse("""{"name":"xyz", "age" : 28}""").getAsJsonObject

      val age2 : Option[Long] = jsonObject2.get("age") match {
        case null => None
        case value => Some(value.getAsLong)
      }

      val person2 = new person(jsonObject2.get("name").getAsString.toLowerCase, age2.getOrElse(0l))

      assert(person2.name == "xyz")
      assert(person2.age == 28)
    }

  }
}

2)如果您想让年龄为Option[Long] Option[T]可以有Some(x)None

class CaseClassFunSpecs extends FunSpec {

 it("converts json to case class with empty age"){

  case class person(name: String, age: Option[Long])

  val parser = new JsonParser()

  val json = parser.parse("""{"name":"xyz"}""").getAsJsonObject()

  val personInstance = new person(json.get("name").getAsString.toLowerCase,
    Option(json.get("age")).map(_.getAsLong))

  assert(personInstance.name == "xyz")
  assert(personInstance.age == None)
  // NOTE
  // do not do personInstance.age.get which would throw
  // None.get
  // java.util.NoSuchElementException: None.get
  // at scala.None$.get(Option.scala:347)
  // at scala.None$.get(Option.scala:345)

  //rather use pattern match
  personInstance.age match {
    case Some(x) => println("value = " + x)
    case None => throw new RuntimeException("Age can not be empty.")
  }
  }

 it("converts json to case class with non-empty age"){

  case class person(name: String, age: Option[Long])

  val parser = new JsonParser()

  val json = parser.parse("""{"name":"xyz", "age" : 28}""").getAsJsonObject()

  val personInstance = new person(json.get("name").getAsString.toLowerCase,
    Option(json.get("age")).map(_.getAsLong))

  assert(personInstance.name == "xyz")
  assert(personInstance.age == Some(28))
  assert(personInstance.age.get == 28) //.get gives you the value 
 }
}
相关问题