【问题标题】:functional scala- how to avoid deep nesting on optional mappings函数式缩放 - 如何避免可选映射上的深度嵌套
【发布时间】:2019-02-09 13:56:26
【问题描述】:

我有一组按顺序完成的操作,但如果中间序列返回“null”,我想提前中止操作(跳过后续步骤)。

我想出了一个像这样的函数,它给定一个输入参数,对 Redis 执行几个操作,如果它存在,它将返回一个产品。由于其中一个中间请求可能返回空值,因此完整的操作可能会“失败”,我想缩短之后出现的不必要步骤。

这里的嵌套变得疯狂,我想让它更清晰。是否有适当的“功能”方式来执行这种类型的"if/else" 短路?

def getSingleProduct(firstSku: String): Option[Product] = {
    val jedis = pool.getResource
    val sid: Array[Byte] = jedis.get(Keys.sidForSku(firstSku, sectionId, feedId).getBytes)
    Option(sid).flatMap {
      sid: Array[Byte] =>
        Option(jedis.get(Keys.latestVersionForSid(sectionId, feedId, sid))) flatMap {
          version: Array[Byte] =>
            Option(Keys.dataForSid(sectionId, feedId, version, sid)) flatMap {
              getDataKey: Array[Byte] =>
                Option(jedis.get(getDataKey)) flatMap {
                  packedData: Array[Byte] =>
                    val data = doSomeStuffWith(packedData)
                    Option(Product(data, "more interesting things"))
                }
            }
        }
    }
  }

【问题讨论】:

    标签: scala functional-programming optional flatmap


    【解决方案1】:

    这样做的方法是使用for:

    for {
      sid <- Option(jedis.get(...))
      version <- Option(jedis.get(..., sid, ...))
      getDataKey <- Option(jedis.get(...version,...))
      packedData <- Option(jedis.get(getDataKey))
    } yield {
      // Do stuff with packedData
    }
    

    如果任何get 调用返回None,这将返回None,否则将返回Some(x),其中xyeild 表达式的结果。

    您可能还想考虑为jedis.get 编写一个包装器,它返回Option(x),而不是使用null 作为错误结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-01
      • 2011-06-21
      • 2015-05-07
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2017-11-07
      • 2019-04-29
      相关资源
      最近更新 更多