4

Option[T]Scalaは、クラスの階層を提供します。これは、特に、Some[T] extends Option[T]None extends Option[Nothing]返すことができるJavaメソッド呼び出しをラップするのに役立つことがわかりました。null

val result = Option(someJavaMethodThatReturnsNull())

resultJavaメソッドがオブジェクトを返したか、を返したかに応じて、0個または1個のアイテムのシーケンスのように機能しますnull。、などのOptionメソッドがあります。これらのメソッドは、シーケンスのメソッドと同じように使用でき、元のシーケンスが。の場合、または元のシーケンスがの場合は、新しいシーケンス()を返します。mapfilterSomeSome[T]NoneNone

Clojure関数seqも同様に動作するようです。xがnullでない場合、(seq x)またはxがnullの場合、1つのアイテムのシーケンスになりnilます。この値は、Scalaメソッドと同じよう(map ...)に、などに渡すことができます。(filter ...)Option

私は何かが足りないのですか?このパターンは意味がありますか?これは「ユーレカ!」ですか 経験豊富なClojureプログラマーにとって明らかな瞬間ですか?

4

4 に答える 4

2

もちろん、静的型安全性なしで、scala Option (および haskell Maybe) に近い Maybe monad をいつでも使用できます。

の家族もいますスレッド関数(.?. は、Java 相互運用に適しています)

于 2011-10-19T15:46:25.387 に答える
2

Clojure シーケンスを使用して、ゼロ、1 つ、または複数の戻り値を表すことができます。

関数が実際にコレクションを返すことが期待される場合、これは賢明なアプローチであり、非常に慣用的です。

ただし、シーケンスを使用してオプション タイプをエミュレートすることはお勧めしません。これは、API のユーザーを混乱させる可能性があります。Clojure では、値が利用できない場合は nil を返し、利用可能な場合は値を直接返すという、通常の慣用的な方法があります。

比較:

  (if-let [a (function-that-returns-nil-or-result)]
    (do-something-with a))

シーケンスを使用してオプション タイプをエミュレートする場合に必要なもの:

  (if-let [a (function-that-returns-a-possibly-empty-sequence)]
    (do-something-with (first a)))  

私は間違いなく最初のオプションを好みます.... APIユーザーがシーケンスから結果をアンパックする必要がある、またはしたいのはなぜfirstですか?

一般に、nil は Clojure で非常にうまく機能します (他の言語よりもはるかに優れています)。理由は次のとおりです。

  • すべてのライブラリ関数は nil を空のシーケンスとして解釈するため、NullPointerExceptions に遭遇する可能性ははるかに低くなります。
  • nil も「falsey」と見なされるため、ブール演算で便利に使用できます。
于 2012-01-11T02:07:42.080 に答える
1

いいえseq、コレクションが空でない場合、コレクションの抽象的で連続したビューを返します。nilそれ以外は。したがって、それはあなたが望むものとはまったく関係ありません。ただしnil、if テストでは使用できます。例えば。

(when-let [thing (.someMethodThatReturnsSomethingOrNil other-thing)]
  (run-only-when thing is-not-nil-or-false))

それがあなたの意図ですか?

編集:誤りに注意してください。

于 2011-10-19T13:24:27.400 に答える
0

(seq x)isまたは空のコレクションのnil場合に返されます。ただし、などはコレクション引数として受け入れ(つまり、壊れません)、空のシーケンスを返します。これにより、Scala のステートメントから期待される結果が得られる場合があります。xnilmapfilternilOption

以下は、それぞれ空のシーケンスを返します。

(map (fn [x] x) (seq nil))
(map (fn [x] x) (seq `()))
(filter even? (seq nil))
(filter even? (seq `()))
于 2011-10-19T14:40:22.600 に答える