2

personFromParams関数が を返すのはなぜNoneですか?

  def personFromParams(p: Map[String, String]): Option[Person] =
    for {
      name <- p.get("name")
      ageStr <- p.get("age")
      age <- toInt(ageStr)
      validStr <- p.get("valid")
      valid <- toBool(validStr)
    } yield { println("personFromParams()"); new Person(name, age, valid) }

   def tryo[T](f: => T): Option[T] = try {Some(f)} catch {case _ => None}

   def toInt(s: String): Option[Int] = tryo(s.toInt);
   def toBool(s: String) = tryo(JBool.parseBoolean(s))

に数値以外の値を与えると、 forがtoInt返されますが、関数 で例外がキャッチされて処理されるときにが中断する理由がわかりません。NoneagetoIntfortryo

4

3 に答える 3

3

for理解はこのように同等に書くことができるので

p.get("name").flatMap{
  name => p.get("age").flatMap {
    ageStr => toInt(ageStr).flatMap {
      age => p.get("valid").flatMap {
        validStr => p.get("valid").flatMap {
          validStr => toBool(validStr).map{
            valid => { println("personFromParams()"); new Person(name, age, valid) }
          } 
        }
      }
    }
  }
}

Option.flatMapのscalaドキュメントから:

この Option が空でない場合、この Option の値に f を適用した結果を返します。この Option が空の場合は None を返します。f が Option (None の場合もある) を返すことが期待されるという点で map とは少し異なります。

于 2012-12-07T13:38:49.130 に答える
2

実行を中断しません。ただ、scala が対象となる age コレクションを探すときに、対象となる要素がありません。

for yield は map と同等であり、ネストされた for yield は set product の次に map と同等であることに注意してください (完全ではありませんが、意味がわかります)。入力セットの 1 つが空の場合、結果セットも空ですよね?

これを解決するには、toInt(age) を通過する行を削除し、これをコンストラクターの引数に入れます。

于 2012-12-07T13:32:58.583 に答える
1
for { a <- Some(3) } println(a) // 3
for { a <- None } println(a)    // no output

forこの動作は予期されるものであり、コンパイラによって a が脱糖される式を見ることで説明できます。上記のスニペットで Scala を実行する-printと、ループが次のように脱糖されることがわかりますforach

new Some(scala.Int.box(3)).foreach({...})
scala.None.foreach({...})

Noneは空のコレクションを表すため、何もする必要はありませんforeach

于 2012-12-07T13:36:59.407 に答える