15

clojureマップがあります。名前を付けoptsます。キーがない場合にデフォルト値を取得するように、このマップから値を取得する2つの方法を知っています。

(let [opts {}
      title-1 (or (:title opts) "Default title")
      title-2 (:title opts "Default title")]
  (println title-1 title-2))

いくつかのライブラリ(quil、incanter)が。で最初のアプローチを使用しているのを見ましたor。2番目のアプローチはより簡潔でクリーンなように思えます。最初のアプローチには利点がありますか?
を使用するデメリットは、(or (:title opts) "Default value")渡すことができなくfalseなりnil、値としてこの場合は常にデフォルト値が使用されることです。

4

2 に答える 2

25

(or (:key hash) default)との決定的な違いは、前者は必要な場合にのみ(:key hash default)評価するという事実です。default後者の場合、常に評価されます。そのためor、評価defaultが高い場合に使用する必要があります。

ブール値のコンテキストで false の値がハッシュに含まれている場合、別の違いが明らかになります。そのような値の場合、代わりにまたは期待(or (:key hash) default)される値が評価されます。式とは対照的に、正しい結果が得られます。補足として、ハッシュに値として格納する前によく考えてください。defaultfalsenilor(:key hash default)nil

いいですね、それらは重要な違いでした。それでは、マイナーなものに移りましょう。

(or (:title opts) "Default title")

読者によって展開されます

;; Redacted for the sake of brevity.
(let* [x (:title opts)]
  (if x
    x
    "Default title"))

おそらく、単純に評価するよりも効率的ではありません

(:title opts "Default title")

もちろん、ベンチマークがなければ速度の違いを推定するのは困難ですが、私はそれがわずかであるべきだと信じています.

一方、慣用句(or (:key hash) :default)に慣れていない人にとっては、一見すると理解しやすいようです。(:key hash :default)他の言語から来たプログラマーを考えてみてください。たとえばRubyでは、ハッシュの存在しない要素を処理するための典型的なアプローチは次のとおりです。

val = hash[:key] || :default

したがって、特定の Clojure のイディオムに慣れていない人間にとっては、最初の式の方が解析しやすいかもしれません。

于 2012-12-11T09:43:19.747 に答える