scala言語学習のOption
3366 ワード
先日、Optionに関する文章を見ましたが、Null Pointerの発明者C.A.R.Hoare先生の話を引用しました。空引用は「10億ドルの誤り」です。
ここでは、戻り値が空の時に空の指針が異常になると主に言っていましたが、戻り値はOptionで包んだら、いずれは一つの対象に戻ります。もう空の引用には戻らないし、Null PointerExceptionもありません。この認識は間違っていませんが、今晩までプレイフレームの初期化コードを見て、Optionがどのような役割を果たしているのかが分かりました。いったいどうやって「10億ドル」を節約できますか?
プレイフレーム初期化時に設定に基づいてNettyServerを作成します。プロセスは以下の通りです。
mapを再参照:
filter類似:
最初の5行のコードを振り返ってみると、すぐにOptionの大きな強みを感じました。こんなに多くのパラメータの準備と検証をして、また空と判断しました。またファイルが存在するかどうかを判断します。カタログとしても、if文がありません。if elseのない副作用はエラー処理であり、とても優雅です。このコードはjavaで書いたら、大体こんな感じです。
振り返ってみると、scalaの他のコードは、基本的にif文がないことが分かりました。この感じは先日erlangを使い始めたばかりの時、erlangコードにはほとんどif文がないことに気づきました。最初はとても違和感があって、プログラムが書けないことに気づきました。でも、とても速くて、case文ですっきりしました。
scalaを見て、javaを書きたくないです。
ここでは、戻り値が空の時に空の指針が異常になると主に言っていましたが、戻り値はOptionで包んだら、いずれは一つの対象に戻ります。もう空の引用には戻らないし、Null PointerExceptionもありません。この認識は間違っていませんが、今晩までプレイフレームの初期化コードを見て、Optionがどのような役割を果たしているのかが分かりました。いったいどうやって「10億ドル」を節約できますか?
プレイフレーム初期化時に設定に基づいてNettyServerを作成します。プロセスは以下の通りです。
def main(args: Array[String]) {
args.headOption.orElse(
Option(System.getProperty("user.dir"))).map(new File(_)).filter(p => p.exists && p.isDirectory).map { applicationPath =>
createServer(applicationPath).getOrElse(System.exit(-1))
}.getOrElse {
println("Not a valid Play application")
}
}
最初はちょっと目まいがしました。こんなに長くて、またmapです。filterです。またorElseがあります。getOrElseです。意味が分かりません。振り返るしかないです。まずOptionのコードを調べてみます。 @inline final def getOrElse[B >: A](default: => B): B =
if (isEmpty) default else this.get
getOrElseは、Optionが空であればパラメータの値を返します。そうでなければOptionの値を返します。ちなみに、ここのパラメータ値のタイプの前に「=」があります。これは後の値を求めるものです。いわゆるcall-by-nameパラメータです。Optionが空でないとパラメータは値を求められません。ここを見て、私達の製品コードの中の一山を思い出しました。以下のjavaコードです。if (log.isDebugEnabled())
{
log.debug("plaplapla");
}
scalaを使って、log.debugのパラメータをcall-by-nameのパラメータと定義すれば、1行だけで解決できます。C++の中のやり方はマクロを定義することであり、醜悪な解決策でもある。mapを再参照:
@inline final def map[B](f: A => B): Option[B] =
if (isEmpty) None else Some(f(this.get))
Optionが空であれば、関数fによってマッピングされたOptionを返します。ここのNoneとSomeはOptionのサブクラスです。filter類似:
@inline final def filter(p: A => Boolean): Option[A] =
if (isEmpty || p(this.get)) this else None
空の場合、またはp関数がfalseに戻り、空のOptionに戻ります。そうでなければ、自分に戻ります。最初の5行のコードを振り返ってみると、すぐにOptionの大きな強みを感じました。こんなに多くのパラメータの準備と検証をして、また空と判断しました。またファイルが存在するかどうかを判断します。カタログとしても、if文がありません。if elseのない副作用はエラー処理であり、とても優雅です。このコードはjavaで書いたら、大体こんな感じです。
public static void main(String[] args) {
String dir = null;
if (args.length == 1)
dir = args[0];
else
dir = System.getProperty("user.dir");
if (dir != null)
{
File f = new File(dir);
if (f.exists() && f.isDirectory())
{
NettyServer server = createServer(f);
if (server == null)
System.exit(-1);
}
else
System.out.println("not a valid play application");
}
else
System.out.println("xxxx");
}
コードの長さはともかく、以前はこのようなJAVAコードの論理がはっきりしていると感じましたが、今はこれらのif elseがこのようにこじれています。振り返ってみると、scalaの他のコードは、基本的にif文がないことが分かりました。この感じは先日erlangを使い始めたばかりの時、erlangコードにはほとんどif文がないことに気づきました。最初はとても違和感があって、プログラムが書けないことに気づきました。でも、とても速くて、case文ですっきりしました。
scalaを見て、javaを書きたくないです。