18

機能的なスタイルを維持しようとすると、いつ優先すべきかを理解するのが困難になります。

(-> [1 2 3] reverse last)

以上:

(last (reverse [1 2 3]))

プロジェクトで両方のスタイルに出くわすと、関数の合成について考えることと中間値の状態について考えることを切り替える必要があるため、流れが途切れることに気付きます。

いつどちらを使うべきですか?

4

5 に答える 5

14

->私は主に1つの引数の関数に使用することを避けています。複数の引数を持つ関数がある場合は、フォーカスオブジェクトがそれを覆い隠すことなく、各関数を「余分な引数」の横に保持できるため、はるかに便利です。

しかし、どちらか一方を選択する必要はありません。私のお気に入りの1つは->、関数を任意の順序で記述できることです。この自由を使用して、任意の方法でコードを記述できます。あなたは最も読みやすいと思います。たとえば、コレクションの最後を取得していることを強調したい場合があります。コンテキストでは、最初に逆になっているという事実は興味深いものではありません。

(last (-> [1 2 3] (reverse)))

または、逆にすることが重要であり、最後は退屈です。

(-> (reverse [1 2 3]) (last))

余談ですが、私が書いたのは、単にかっこを省略した場合にマクロが暗黙的にかっこを挿入したとしても、ここではなく(last)、ここに書いたことに注意してください。これは意図的なものでした。それほど人気のあるスタイルではありませんが、に指定された形式では常に括弧を使用することをお勧めします。これにはいくつかの理由があります。(reverse)lastreverse->->

  • これは、関数ではなく形(-> (blah) (fn [x] (+ 1 (* x 5))))をとるという考え方に慣れているため、奇妙に展開しても驚かないことを意味します。->
  • 「ここに開き括弧があります」と「関数が呼び出されています」の間のリンクを維持します。特定の関数の呼び出しをgrepできるのは素晴らしいことであり、視覚的なヒントでもあります。括弧を省略すると、視覚的に通知されることなく関数が呼び出されます。
  • ->いくつかの単項関数や他の複数引数関数を含む複数行では、より規則的に見えます。例えば:

    (-> attrs
        (update :sessions inc)
        frobnicate
        save-to-disk
        (get :uuid))
    

    真ん中のオフセットにこれら2つのものがあり、他のすべてのものとは異なって見えるのは、ひどいことではありませんか?

sを省略するために私が今まで見た唯一の引数()は、2文字の入力を節約するということですが、これはまったく引数ではありません。

于 2012-10-03T20:51:50.213 に答える
9

私の経験則は、「どちらがより宣言的な英語の文に近いか」です。それらを大まかに説明文に翻訳すると、結果を作成するプロセスを説明するオプションよりも、作成されるものをより厳密に表すものを選択する傾向があります。一部の人々は他の方法を選択したいと思うでしょう。これらは常に好みの問題です。

例えば:

  • (last (reverse [1 2 3]))ほぼ「123を逆転させてから最後」です
  • (-> [1 2 3] reverse last)「123から、逆に、最後に取る」のようなものです

私は最初のより宣言的なものを見つけ、この場合はそれを選択しますが、他の人は別の方法で選択します。

于 2012-10-03T20:15:52.600 に答える
8

それらは機能的に同一であるため、考慮すべき主なことは、コードをより読みやすく、保守しやすくすることです。

これは基本的に判断の呼びかけです。

->多くの場合、次のような状況で役立ちます。

  • 順番に実行する一連の操作があることを明確にしたい
  • 将来、新しいステップを挿入することをお勧めします。簡単-新しい行/フォームを追加するだけです。
  • ステップにはいくつかの追加の引数があります(これらの引数がステップの一部であることが非常にわかりやすくなります)
  • 深くネストされた関数呼び出しは、そうでなければ混乱を招きます(ただし、これが本当に問題である場合は、リファクタリングする他の方法があります...)。

(f (g x))スタイルは他の状況で役立ちます:

  • 数学関数の表記をより厳密に反映しているため、数学演算/計算ではより自然なスタイルであることがよくあります。
  • ->渡される値が常に最初(with )または最後(with ->>)の引数でなければならないという要件がないため、より柔軟性があります。
  • 余分な議論を想像しなければならないという精神的なオーバーヘッドはありません
于 2012-10-04T04:09:57.767 に答える
3

すでに回答した人には同意しますが、Cを使用する多くの人と作業している場合は、後者の形式の方が読みやすいと思いますが、C#の教祖が多い場合は、 、拡張メソッドと比較して、以前の形式に精通しているでしょう。

于 2012-10-03T21:07:11.680 に答える
3

他の答えには何の問題もありませ->んが、私にとって本当に理にかなっているのは、一連の操作が適用されていることを強調したい場合です。左から右に読むと、関数が評価される順序が自然にわかります。これは、ネストのレベルが2または3を超えると非常に役立ちます。長い形式では、かっこを頭の中で解析し、最低レベルまでドリルダウンしてから、何が起こっているのかを理解するために戻っていく必要がある場合があります。

于 2012-10-04T02:48:01.007 に答える