如何以惯用的方式在Scala中进行空检查?

时间:2016-11-06 00:19:26

标签: scala

case class Account(
                          val name: String,
                          val uuid: String,
                          val lat: Double,
                          val lng: Double
                        )
}

object Account {
  def create(row: Row): Option[YellowAccount] = {
    val name = row.getAs[String]("store_name")
    val uuid = row.getAs[String]("uuid")
    val latO = row.getAs[String]("latitude")
    val lngO = row.getAs[String]("longitude")

    // How do you do null checks here in an idiomatic way?
    if (latO == null || lngO == null) {
      return None
    }

    Some(YellowAccount(name, uuid, latO.toDouble, lngO.toDouble))
  }

}

lat / long是Account中的必填字段。你如何以惯用的方式做空检查?

2 个答案:

答案 0 :(得分:4)

您可以使用Option类型来处理null值。您只需在Option中包含一个可以为空的值,然后就可以对其进行模式匹配。在您的示例中,我认为组合4个可空值的最简洁方法是for-comprehension:

import scala.util.Try

object Account {
  def create(row: Row): Option[YellowAccount] = {
    for {
      name <- Option( row.getAs[String]("store_name") )
      uuid <- Option( row.getAs[String]("uuid") )
      latO <-    Try( row.getAs[String]("latitude").toDouble ).toOption
      lngO <-    Try( row.getAs[String]("longitude").toDouble ).toOption
    } yield 
      YellowAccount(name, uuid, latO, lngO)  
  }
}

修改

此处的另一件事是_.toDouble转换,如果它无法解析字符串,可能会抛出异常,因此您可以将其包装在Try中(我更新了上面的代码)。

<强> EDIT2

澄清这里发生的事情:

  • 当您在Option中换行值时,如果值为None,则变为null,否则为Some(...)
  • 类似地,当包装可能在Try中引发异常的内容时,它会变为Failure(例外)或Success
  • toOption方法以直接的方式将Try转换为OptionFailure变为NoneSuccess变为Some < / LI>
  • 在for-comprehension中,如果四个Option任何返回None(即其中一个null未能解析数字) ,整个语句返回None,并且只有当中的每个产生一个值时,它们才会传递给YellowAccount构造函数

答案 1 :(得分:0)

正如另一个答案所示,您可以使用temp\Win来处理可能的空值。你不能按照它的建议方式使用Option理解,但有几种方法可以解决它。最简单的,可能是将for两个选项放在一起,然后映射结果:

.zip