質問

オプションモナドの作業はどのように働いていますか?私は閲覧しています SCALA API そして、例があります(私は2番目のものを意味します)、

理解の仕組みのために、request.getParameterから返品されていない場合、式全体がなしになります

しかし、私がこのコードを試すとき:

 val upper = for {
   name <- None //request.getParameter("name")
   trimmed <- Some(name.trim)
   upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
 } yield upper
 println(upper.getOrElse(""))

コンパイルエラーが発生します。これはどのように機能するはずですか?

役に立ちましたか?

解決

このため、コンパイラエラーが発生します

  name <- None

そうすれば、タイプ None に設定されています None.type そして変数 name タイプであると推測されます Nothing. 。 (つまり、それが実際に存在した場合、このタイプはこのタイプを持っているでしょうが、明らかに理解のためのものは実行時にそれを作成することさえしません。)したがって、方法はありません name.trim 存在するとコンパイルされません。

あなたが持っていたら request.getParameter("name") 利用可能、そのタイプはそうです Option[String], name 潜在的にタイプがあります Stringname.trim コンパイルします。

これを回避できます。 None:

  name <- None: Option[String]

他のヒント

ケビンの答えを拡張するために、値を包むことを避けることができます Some() を使用して = の代わりにオペレーター <- オペレーター:

val upper = for {
   name <- None: Option[String] //request.getParameter("name")
   trimmed = name.trim
   upper = trimmed.toUpperCase if trimmed nonEmpty
} yield upper

理解のために、ケビンのバージョンに非常によく似たものにコンパイルされますが、使用する方が明確であることがよくあります mapfilter 式のセマンティックコンテンツに何も追加しない混乱(たとえば、余分な変数名)を避けるために明示的に。

Debilskiの答えを拡張するには、後続の値を明示的に巻き付ける必要もありません Some(), 、あなたが実際にマッピングしている唯一の値はオリジナルです name.

より良いアプローチは、を使用することです mapfilter 理解のために直接操作:

注:舞台裏では、SCALAコンパイラはとにかくMAP/FLATMAP/フィルターの組み合わせに充足を変換するため、このアプローチは理解のための効率が低く、より効率的である可能性があります。

def clean(x:Option[String]) = x map { _.trim.toUpperCase } filterNot { _.isEmpty }

val param = None : Option[String] // request.getParameter("name")
println( clean(param).getOrElse("") )
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top