在Scala中使用Some()和Option()

Jac*_*ack 8 scala

我一直在与Scala中解析JSON字符串的功能方法的概念作斗争,并在返回选项(某物)的情况下平放到墙上.我弹出问题,有用的答案流入.

问题是,作为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)
  }
}
Run Code Online (Sandbox Code Playgroud)

我仍然坚持使用Some()

解决我的问题有一个很好的模式吗?当然,这必须是一个很好的探索领域.我该如何改进我的代码?

oxb*_*kes 35

你并没有"陷入困境" Some- 你有一个优势,你有一个Some!在Java中,你会遇到一个值,它的类型没有表达它可能实际上不存在的事实!

MyThing recklessly = apiCall.getMeAThing();
recklessly.iSureHopeImNotNull();  //OH NOES!
Run Code Online (Sandbox Code Playgroud)

与此相比

apiCall.getMeAThing foreach (_.cannotPossiblyBeNull)
Run Code Online (Sandbox Code Playgroud)

Option数据类型是指你查询的"可能不存在"位实际上是烤到查询的返回类型.请坚持Option- 几个星期后,当你去编写Java代码时,你会拔出你的头发,但它不存在!

击落你的反对意见

你可能会说:

噢,但我需要拿走我的价值并加1

我说:

apiCall.getMeAThing map (_ + 1)
Run Code Online (Sandbox Code Playgroud)

你可能会说

噢,但我需要将它传递给一个方法,如果我有null,则默认为空String

我说:

foo( apiCall.getMeAThing getOrElse "" )
Run Code Online (Sandbox Code Playgroud)

你可能会说

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

我说:

apiCall.getMeAThing flatMap apiCall.getMeAnotherThing
Run Code Online (Sandbox Code Playgroud)

你肯定会说

噢,但是对于所有这些对象创作来说效率非常低

我说:"试试看,它会很好"


Dan*_*mon 9

通常当你有包裹在一个选项的结果,你想要么使用match或的单子方法中的一种map,flatMapforeach.例如,在您的情况下,我们可以做任何这些

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"))
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,你应该避免像:

if (z == None) {
  println("Invalid")
} else {
  println(Z.get)
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个糟糕的建议; 你应该更喜欢`getOrElse`,`map`,`flatMap`等来匹配`match` (3认同)
  • 我认为这里应该是不言而喻的,与我所包含的其他例子相比,Option上的模式匹配过于冗长,但是提问者似乎并不知道使用它的方法,所以我只是概述了各种方法. (2认同)