私が働いているプロジェクトでこの関数を見つけました:
-- Just returns the text unchanged.
-- Note: <text> may be nil, function must return nil in that case!
function Widget:wtr(text)
return text
end
残念なことに、このコーダーは社内でもう機能していません。何もしない関数を作成し、それが呼び出されたパラメーターを返すのはなぜですか?
この例では指定されていませんが、全体的にこのような関数の用途はありますか?
のため
function aFunction(parameter)
return parameter
end
で終わる
aFunction(parameter) == parameter
なぜ私は次のようなものを書くのでしょうか
aFunction(parameter) == whatIWantToCheck
の代わりに
parameter == whatIWantToCheck
?
あなたの質問は、何かにそれを追加するたびに同じ値が返される場合、ゼロの何が良いかを尋ねるようなものです。恒等関数は、関数のゼロのようなものです。それ自体は役に立たない種類ですが、高次関数を使用する式の一部として役立つ場合があります。この場合、関数をパラメーターとして取得したり、結果として返すことができます。これが、ほとんどの関数型プログラミング言語の標準ライブラリにid
またはidentity
がある理由です。
言い換えれば、それは便利なデフォルト関数を作ります。 offset = 0
をデフォルトの整数として設定するのと同じように、オフセットによって何も実行されない場合でも、filterFunction = identity
をデフォルトの関数として設定できると便利です。フィルターは何もしません。
承知しました。絶対に必要な場所から物事を取得できる外部APIを想像してください。ただし、all結果が必要な場合でも、クエリごとにフィルター条件と出力フォーマッターを指定する必要があります。 正確に保存されたとおり。
次に、データを取得するために、ささいな「すべてを受け入れる」関数とささいな「変更を返す」関数を発明する必要があります。 wtr
は、まさにそのような些細な疑似フォーマッターです。そのAPIを頻繁に使用する場合、何かをクエリするときに無名関数を作成する必要はなく、この疑似ヘルパー関数を配置しておくと非常に便利です。 (何もしないことがすぐにわかるように、identity
ではなくwtr
と呼ぶことを検討してください。)
それは単なる多態性ではないですか?
Qtでの私の経験から、tr()
およびwtr()
メソッドは、Widget
のローカライズで(Qtで)使用されることになっていますテキスト。
したがって、変更されていないテキストを返すことにより、このメソッドはWidget does no localization (translation of the text) by default. Override this function to enable your own logic
と言います。
この非常に一般的なケースは、「後で追加された機能」です。そのため、プログラマーは後でその関数に変更が加えられる可能性があると考えました。パラメータ自体としてではなく関数としてアクセスするため、これを簡単にグローバルに変更できます。次のようなインデックスがあるとします。
function getIndex(index)
return index
end
インデックスは0から始まるため、これで問題ありません。後でコンポーネントを別の場所に変更します。このコンポーネントでは、インデックスを1から開始するように変換する必要があります。コード内のどこにでも数百のindex + 1を追加する必要があります。しかし、このような方法では、次のように言うだけです。
function getIndex(index)
return index+1
end
あなたは元気ですこのような関数はすぐにオーバーエンジニアリングにつながる可能性がありますが、いくつかの点でそれらは非常に理にかなっています!
このようなスタブ関数は、型継承の状況では一般的です。基本クラスは何も役に立たないかもしれませんが、派生クラスは入力に対してさまざまなことを行う可能性があります。基本クラスでスタブ関数を宣言すると、すべての派生クラスがhaveその名前の関数になり、個々の派生クラスがoverrideになり、より複雑で便利なものになります。
追加のシナリオの1つは、pythonおよびプロパティのC#での使用と似ていますが、機能を持たない言語での使用です。
一般に、クラスのメンバーとしてのみ宣言できます。文字列としての「名前」としましょう。つまり、次のようにアクセスします。
someobject.name
後で、名前は本当にオブジェクトの内容に依存する必要があると判断しました。だからそれは本当に関数であるべきです。おっとっと!引数がなくても、これにアクセスするすべてのコードを次のように変更する必要があります
someobject.name()
しかし、この呼び出しのインスタンスが多数ある場合、何も問題が発生しない可能性はかなり低くなります。この変更が行われない場所では、そのポイントに到達するとプログラムがクラッシュします。
C#/ Pythonのプロパティを使用すると、以前は属性であったものを関数に置き換えることができますが、属性のように、つまり変更せずにアクセスできます。事前に計画を立てる必要もありません。
言語にそれがない場合は、事前に計画する必要がありますが、最初から何もしない関数にすることで、以前と同じようにサポートすることができます。最初は、何もおもしろくなく、削除する必要があるように見え、このタイプの多くの関数は決して変更されません。しかし、後で実際にWidget.wtr
を呼び出すたびにいくつかの特殊文字を削除する必要があることに気付いた場合、それは大した問題ではありません。すでに関数なので、それを追加するだけで完了です。
TL; DRこれは、将来の変更に備えて計画している賢明なプログラマにすぎません。
これは役に立たないわけではありません。コードがより均一で柔軟になるため、実際には非常に便利です。
たとえば、「すべて」を表示するか、「男性」または「女性」のみを表示するかをユーザーが選択できるドロップダウンとユーザーのリストがあるとします。
「すべて」を特別なケースとして処理することができます。この場合、このケースを明示的に確認するために追加で必要になるか、またはそのパラメーターを返すだけのフィルター関数を持つことができます(たとえば、すべてを渡すことができます)。 「すべて」の場合に使用するように割り当てられています。