2011-07-25 4 views
16

私はしばしばErlang関数がok、または{ok, <some value>}、または{error, <some problem>}を返します。いつErlang関数が正常に戻りますか?

私の関数が整数Nを返すと仮定します。私の関数はただNを返しますか?{ok, N}

または、私の機能には電話io:function("Yada yada")が含まれているとします。それはokを返しますか、まったく何も返しませんか?

または、私がレコードや楽しいことをしているとします。 {ok, R}または(ok, F}を返す必要がありますか?

おかげで、

LRP

答えて

22

これはスタイルの問題ですが、合理的な選択をすることは、コードをより読みやすく保守しやすくするための道のりです。ここではいくつかの私自身の好みに基づいた思考と私は標準ライブラリに表示されている。

  • 関数が成功し、回復可能な失敗のケースの両方で返すことができる場合、あなたは成功事例が{ok, _}かのように見てみたいことがありますok。良い例は、orddict:find/2application:start/1です。これを行うことで、電話をかけるときに両方のケースを簡単にパターンマッチングさせることができます。
  • 意味のある結果を持つ成功事例のみがある場合は、追加情報を追加する必要がないため、結果を返します。実際、タプルで結果をラップすると、呼び出しを簡単に連鎖させることはできません。 bar/1{ok, _}を返す場合、foo(bar(N))が機能しない可能性があります。良い例は、lists:nth/2math:cos/1です。
  • 意味のある結果が得られていない成功事例しかない場合、関数内で最後に返された値が何であっても、共通のイディオムはokまたはtrueを返します。良い例は、ets:delete/1io:format/1です。
+4

私が作っておきたいことは、ユーザがエラーを処理できることが意味を持つならば、 '{error、Reason}'だけを返すべきことです。回復不可能なエラーの場合は、例外としてスローされる方がよい。 –

+0

'リスト:nth/1'は、そのような良い例ではありません。なぜなら、それは(ユーザーが処理できるはずの)失敗のケースを持っているからです。 –

+1

これは有効な例です。 'lists:nth/2'は無効な入力が与えられた場合にのみ失敗します。 'math:cos(foo)'も同じように失敗します。どちらも回復不可能なため、例外がスローされます。私がそれを記述したパターンは、回復可能なエラーだけを参照しています(Adamのコメントを参照)。 –

5

と仮定し、私の関数が返す整数N.万一私の関数の戻り値だけN、または{OK、N}?

エラーの可能性が全くないか、エラーがプログラミングエラーの場合は、Nです。失敗する必要がある場合は、{ok, N}(および失敗の場合は{error, Reason})を返します。

戻っても何も返されませんか?

Erlangでは、は何も返しません。意味のある戻り値がない場合、okは問題ありません。

1

これは私が多くのアチームで自分を見つけることです。親指のルール(少なくとも私の親指)は、関数が主に他の関数(map()、filter()などの高次関数)で使用される場合、または関数が「純粋に」なるように設計されている場合、 (副作用がない)場合は、{ok、_}を返さずに結果を返すことを好むでしょう。この場合のエラーは、修正すべき論理的/アルゴリズム的なエラーのためでなければならず、関数のクライアントはそのようなエラーを認識する必要があります。

+0

これはなぜdownvotedされた何らかの理由は? –

+0

おそらく答えは少し広がっているかもしれません - あなたが行っている方向が気に入っていると思いますが、あなたが何を意味しているのかを新人に伝えるためには、 "関数が* composable *と* pure * - >が' ok'を返さないならば、 'ok'か' {ok、Result} 'を返すべきで、それはコードですいずれにせよ、これは確かに多くの場合に有用な概念です。 – zxq9

関連する問題