2017-01-09 8 views
1

次のコードで第3のprintlnと混乱します。出力はNoneです。私の理解によると:スカラのオプションのマップ機能

  1. lookupPlayer(3)が続いNonemapが呼び出されます
  2. Option[Nothing]のサブタイプがあるNoneを与えるだろう。しかしNonemapの機能はどのように機能しますか?

私は簡単な例で理解してください。 docsから

case class Player(name: String) 

def lookupPlayer(id: Int): Option[Player] = { 
    if (id == 1) Some(new Player("Sean")) 
    else if(id == 2) Some(new Player("Greg")) 
    else None 
} 

def lookupScore(player: Player): Option[Int] = { 
    if (player.name == "Sean") Some(1000000) else None 
} 

println(lookupPlayer(1).map(lookupScore)) // Some(Some(1000000)) 
println(lookupPlayer(2).map(lookupScore)) // Some(None) 
println(lookupPlayer(3).map(lookupScore)) // None 
+0

2つ目の点として、NoneのマップはNoneを生成します:Optionのソースコードを見ることができます。 – bhericher

答えて

5

:だから

final def map[B](f: (A) ⇒ B): Option[B]

Returns a scala.Some containing the result of applying f to this scala.Option's value if this scala.Option is nonempty. Otherwise return None.

- 簡単に言えば、None.map(<any function>)戻りNone

+0

しかし、どのようthisscala約> None.map(X => X +1) :12:エラー:値+がNothing None.map(X => X +1) ^スカラ>のメンバーではありません。 None.map(x => 1) res32:オプション[Int] = None、ここでは関数x => x +1に対してはNoneを指定していますが、むしろエラーを出しています。別の疑問は、Nothingにインスタンスがない場合、xがNothingのインスタンスであることです。 –

+0

@PriyaranjanSwain - 2番目の例では、関数内の 'Nothing'を無視し、定数' 1'を返します。 'None map'は 'f'を呼び出さずに即座に' None'を返さなければならないので( 'f'を呼び出すための' A'値がないので)、 'Nothing'型の値はないので、関数は決して実行されません。 – Lee

+0

まず、_runtime_と_compilation_エラーの違いに注意してください。もちろん、 'f'は決して実行されなくても_compile_する必要があります。この場合、 'None'を使用した場合、型パラメータ' B'の値となる 'Any'で+が定義されていないため、コンパイルできません。しかし、明示的に型指定された 'Option'の値として' None'を使うと、これはコンパイルして 'None'を返します:' val o:Option [Int] = None; o.map(_ + 1) '。 –

0

単純な言葉で表現する操作は、x1からx2に変換することを意味します。ここではx1とx1は

scala> Some(1).map(x => x * 2) 
res10: Option[Int] = Some(2) 

と同じタイプのものとすることができるいずれか、またはmap操作の出力を変換するものがないとき、それは別の種類の

scala> Some(1).map(x => x.toString) 
res11: Option[String] = Some(1) 

ことができますが、何もありません。 Noneのマップ関数は常にNoneを返します。

scala> None.map((x: Int) => 0) 
res1: Option[Int] = None 

これは、Optionクラスのmap関数の定義です。 OptionNoneの場合、isEmptyメソッドはtrueを返します。したがって、Noneのマップは常にNoneを返します。

@inline final def map[B](f: A => B): Option[B] = 
    if (isEmpty) None else Some(f(this.get))