【问题标题】:Working with Some() and Option() in Scala在 Scala 中使用 Some() 和 Option()
【发布时间】:2012-02-22 03:28:54
【问题描述】:

我一直在与在 Scala 中解析 JSON 字符串的函数式方法的概念作斗争,并在返回 Option(something) 的情况下遇到了问题。我popped the question和有用的答案进来了。

问题是,作为一个刚接触 Scala 的人,正确的方法是什么?

目前我正在这样做:

import util.parsing.json.JSON._

object JsonSoap {
  def main(args: Array[String]) {
    val x = parseFull("""{"name":"Joe","surname":"SOAP"}""")

    val y = x collect {
      case m: Map[_, _] => m collect {
        case (key: String, value: String) => key -> value
      }
    }

    val z = for (m <- y; name <- m.get("name"); surname <- m.get("surname"))
    yield {
      <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Body>
          <Person>
            <Name>{name}</Name>
            <Surname>{surname}</Surname>
          </Person>
        </soap:Body>
      </soap:Envelope>
    }

    println(z)
  }
}

我仍然坚持使用 Some()

有没有很好的模式来解决我的问题?当然,这必须是很好探索的领域。如何改进我的代码?

【问题讨论】:

    标签: scala


    【解决方案1】:

    您不会“卡在”Some - 您拥有Some优势!在 Java 中,您会遇到一个类型无法表示它实际上可能不存在的值!

    MyThing recklessly = apiCall.getMeAThing();
    recklessly.iSureHopeImNotNull();  //OH NOES!
    

    对比一下

    apiCall.getMeAThing foreach (_.cannotPossiblyBeNull)
    

    Option 数据类型意味着您的查询的“可能不存在”位实际上已包含在查询的返回类型中。请坚持使用Option - 几周后,当您开始编写 Java 代码时,您会感到头晕目眩!

    消除你的反对意见

    你可能会说

    哦,但是我需要将我拥有的值加 1

    我说:

    apiCall.getMeAThing map (_ + 1)
    

    你可能会说

    哦,但是我需要将它传递给一个方法,如果我有 null,则默认为空字符串

    我说:

    foo( apiCall.getMeAThing getOrElse "" )
    

    你可能会说

    哦,但我使用该值来调用另一个 API 方法并获取其他内容

    我说:

    apiCall.getMeAThing flatMap apiCall.getMeAnotherThing
    

    你肯定会说

    哦,但是所有这些对象的创建效率都非常低

    我说:“试试看就好了”

    【讨论】:

    • 感谢 Oxbow。点;-)
    • Option 类的广告 :) 为其他强制功能样式的 scala 类制作这样的(甚至是视频!!!)广告可能是有意义的 :))))))))跨度>
    【解决方案2】:

    通常,当您将结果包装在选项中时,您希望使用matchmapflatMapforeach 的单子方法之一。例如,在你的情况下,我们可以做任何这些

    val output = z match {
      case Some(xml) => xml
      case None => "Invalid JSON"
    }
    println(output)
    
    //or
    z.foreach{println} //won't print anything if z is None
    
    //or
    println(z.getOrElse("Invalid JSON"))
    

    在大多数情况下,您应该避免这样的事情:

    if (z == None) {
      println("Invalid")
    } else {
      println(Z.get)
    }
    

    【讨论】:

    • 这是个糟糕的建议;你应该更喜欢getOrElsemapflatMap 等而不是match
    • 我认为与我包含的其他示例相比,这里应该不言而喻,选项上的模式匹配过于冗长,但提问者似乎不知道使用它的方法,所以我只是给出各种方法的概述。
    • 好吧,即使帖子已被编辑,我似乎也无法删除我的反对票
    【解决方案3】:

    事情是这样的:你可能没有得到你期望的数据,在这种情况下不可能计算z。所以你的问题的答案真的取决于你的对一个问题的回答:当你不能计算z时你会怎么做?

    假设,例如,如果z 无法计算(即None),您不想打印任何内容。在这种情况下,您可以这样做:

    z foreach println
    

    【讨论】:

      猜你喜欢
      • 2020-10-08
      • 2014-03-08
      • 1970-01-01
      • 2017-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      相关资源
      最近更新 更多