18

私は混乱しています。には、署名付きTraversableLikeの関数がありますflatMap

flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): Iterable[B]

しかし、私はそれをこのように使用することができます

scala> Iterable(1,2,3,4,5).flatMap{i=>if (i%2==0) {None} else {Some(i)}}
res1: Iterable[Int] = List(1, 3, 5)

なぜそれが可能ですか?はどのように にOption変換されGenTraversableOnceますか? サブクラスとは思えない…

4

3 に答える 3

20

クラス ダイアグラム (*) でわかるように、Optionは のサブクラスではありませんが、GenTraversableOnceに利用できる暗黙の変換がありIterableますGenTraversableOnce

ここに画像の説明を入力

(*) ええ、わかりました、だまされました。クラス図はまだ Scaladoc で利用できません...しかし、明日になるはずです! :-)

于 2012-07-11T21:40:33.230 に答える
17

実際、デフォルトで Some[X] から GenTraversableOnce[X] への暗黙の変換があります。これは、REPL でテストするのが非常に簡単です。

scala>  implicitly[Function[Some[Int],GenTraversableOnce[Int]]]
res1: Some[Int] => scala.collection.GenTraversableOnce[Int] = <function1>

scala> implicitly[Some[Int] => GenTraversableOnce[Int]] // alternative syntax
res2: Some[Int] => scala.collection.GenTraversableOnce[Int] = <function1>

実際、これはオブジェクト Option で定義されています。scala パッケージ内:

object Option {
  /** An implicit conversion that converts an option to an iterable value
   */
  implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList

  /** An Option factory which creates Some(x) if the argument is not null,
   *  and None if it is null.
   *
   *  @param  x the value
   *  @return   Some(value) if value != null, None if value == null
   */
  def apply[A](x: A): Option[A] = if (x == null) None else Some(x)

  /** An Option factory which returns `None` in a manner consistent with
   *  the collections hierarchy.
   */
  def empty[A] : Option[A] = None
}

option2Iterable はまさにあなたが探しているものです。また、REPL でテストすると、GenTraversableOnce の実装がリストであることがわかる理由もわかります。

何もせずに自動的にインポートされる暗黙的な変換 (暗黙的に使用する REPL で確認できるものなど) を探している場合は、以下を確認する必要があります。

  • Predef.scala
  • クラスのコンパニオン オブジェクト
于 2012-07-11T09:46:25.787 に答える
3

実際に暗黙的に に変換されているようListです。

scala> val l:scala.collection.GenTraversableOnce[Int] = Some(3)
l: scala.collection.GenTraversableOnce[Int] = List(3)

scala> val l:scala.collection.GenTraversableOnce[Int] = None
l: scala.collection.GenTraversableOnce[Int] = List()

個人的なメモ: scala マジックの暗黙的な変換は、時々本当に混乱します。

于 2012-07-11T09:18:12.877 に答える