加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在Scala中进行空值检查的最佳做法

发布时间:2020-12-16 19:04:54 所属栏目:安全 来源:网络整理
导读:我明白,在 Scala中,null被皱眉,而且应该总是包含一个Option中的可选值(如果有的话可以使用“null”类型). 优点是明确的,不应该需要检查空值,结果代码更安全,更愉快阅读. 然而,实际上,没有什么可以阻止一个值为null – 该规则不是由编译器执行的,更是一个绅士
我明白,在 Scala中,null被皱眉,而且应该总是包含一个Option中的可选值(如果有的话可以使用“null”类型).

优点是明确的,不应该需要检查空值,结果代码更安全,更愉快阅读.

然而,实际上,没有什么可以阻止一个值为null – 该规则不是由编译器执行的,更是一个绅士的协议.例如,当与Java API进行交互时,这可能会很容易中断.

这是最好的做法吗?比方说,我需要编写一个Url案例类,并且可以从java.net.URI创建此类的实例:

object Url {
  def apply(uri: URI): Url = Url(uri.getScheme,uri.getHost,uri.getRawPath)
}

case class Url(protocol: String,host: String,path: String) {
  def protocol(value: String): Url = copy(protocol = value)
  def host(value: String): Url = copy(host = value)
  def path(value: String): Url = copy(path = value)
}

一个URI实例可以为getScheme,getHost和getRawPath返回null.在apply(URI)方法(例如require语句)中,是否足以防范这些问题?在技??术上,为了完全安全,最好保护协议,主机和路径助手方法以及构造函数,但这听起来像是大量的工作和样板.

它是否被认为是安全的,而不是保护API已知接受/返回空值(在我们的示例中为URI),并假设外部调用者将不会传递空值或者只有自己负责?

解决方法

在处理纯函数时,总是更好地坚持总体实现,而不是使用null,require或exception throwing来对数据中的所有故障进行编码.类似于Option和Either的都是这样的.他们都是单子,所以你可以使用“for”的功能.

对代码的以下修改显示了一个总功能应用,当输入的Java URI不提供空值时,该函数只产生一个有意义的值.我们通过将结果包装在Option中来编码“有意义”的概念.

object Url {
  def apply(uri: java.net.URI): Option[Url] =
    for {
      protocol <- Option(uri.getScheme)
      host <- Option(uri.getHost)
      path <- Option(uri.getRawPath)
    }
    yield Url(protocol,host,path)
}

case class Url(protocol: String,path: String)

函数Option是一个标准的空值检查函数,它将null映射为None,并在Some中包装值.

关于您的“设置”功能,您可以使用Option来实现空检.例如.:

case class Url(protocol: String,path: String) {
  def protocol(value: String): Option[Url] = 
    Option(value).map(v => copy(protocol = v))
  // so on...
}

不过我会反对的.在Scala中,通常不要使用null,因此当您从Java库获取值时,通常只能对“bridge”API执行空处理.这就是为什么在从java.net.URI转换时,空值检查确实是完美的,但之后,您在Scala世界中不应该有空值,因此空值检查简单地变得冗余.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读