関数は変更されていないパラメーターのみを返しますが、役に立ちませんか?


15

私が働いているプロジェクトでこの機能を見つけました:

  -- 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



13
@gnat一体どういうことですか?
キリアンフォス14

13
え?この関数はそのパラメータを返しますthis
キリアンフォス14

11
@gnat問題は誰かが自分自身を返すこと以外は何もしない関数を書く理由です。はい、メソッドチェーンを許可するために特定のオブジェクトまたは値を返すことができますが、それは彼の質問ではありません。彼の質問は、誰かがなぜint getParam(int param) { //DO NOTHING return param; } メソッドチェーンの観点から、OPの関数をメソッドチェーンから外すことができ、単一の違いを生むことができないため、完全に冗長で不必要な呼び出しのようなものを書く理由です。
ZeroStatic 14

4
これはおそらくオフトピックであり、luaには適用されませんが、PHPには有効なユースケースnew Foo()->method();があります。古いバージョンでは有効な構文ではなくfunction with($what) { return $what; }; with(new Foo())->method();、回避策として次のような構造が使用されていました。
DCoder

回答:


57

あなたの質問は、何かにそれを追加するたびに同じ値を取り戻す場合、数字のゼロの良いところを尋ねるようなものです。恒等関数は、関数のゼロに似ています。一種の役に立たないが、高次関数を使用する式の一部として役立つ場合があり、関数をパラメーターとして使用したり、結果として返すことができます。ほとんどの関数型プログラミング言語を持っている理由ですididentity彼らの標準ライブラリに。

別の言い方をすれば、便利なデフォルト関数になります。offset = 0デフォルトの整数として設定したいのと同じように、オフセットによって何も行われないfilterFunction = identity場合でも、フィルターによって何も行われない場合でも、デフォルトの関数として設定できると便利な場合があります。


フィルター関数はブール値を返すべきではありませんか?この場合、「ゼロ」フィルター関数がtrueを返します。
キリルラクマン14

1
次に、@ cypressiousマップ関数。
サピ14

6
または、デザインコンセプトの下にそれを貼り付ける:ヌルオブジェクトパターン、機能エディション
blgt 14

@cypressious、それは、引数として渡される述語のためになるfilter高階関数。一次filter関数のタイプは[a] -> [a]
Karl Bielefeldt

たとえば、C#、私に頻繁に使用する.OrderBy(x => x)
CodesInChaos

27

承知しました。絶対に必要な場所から物事を取得できる外部APIを想像してください。ただし、すべての結果が必要で、保存されたとおりに正確に取得する場合でも、すべてのクエリにフィルター条件と出力フォーマッターを指定する必要があります。

次に、データを取得するために、単純な「すべてを受け入れる」機能と、単純な「変更しないで返す」機能を考案する必要があります。wtrまさにそのような些細な擬似フォーマッタです。このAPIを頻繁に使用する場合は、何かを照会するたびに匿名関数を作成する必要はなく、この疑似ヘルパー関数を使用すると非常に便利です。(あなたはそれを呼び出して検討するかもしれないidentityというよりもwtr、すぐに、それは何もしません明らかだように。)


私はまだ感覚を本当に理解していませんでしたが、それはまさにシナリオです。あなたの答えを念頭に置いてこのプロジェクトに取り組んで、しばらくすると理解するかもしれません。ATMそれは私が生データを得た場合、なぜ私は...、関数が再び私の生データを与えたいと思うだろう...、私には無用に見える
Sempie

3
@Sempie繰り返します、APIにフォーマット関数が必要な場合、変更されていないテキストを取得する唯一の方法は、関数がテキストに対して何もしない場合です。
ドーバル14

3
言い換えると、フィルター/フォーマット引数を渡す必要がある関数があり、引数として絶対に使用できない場合null、「nothing」でフィルターして空のフィルター関数を使用し、プログラムが文句を言うのを止めます。
ZeroStatic 14

3
@Sempie SQLを使用したことがありますか?WHERE句を含めるか含めないかを知っていますか?それは大まかに構文糖衣の問題です。基本的にWHERE句がないことは、WHERE先に進んですべてを許可する句がある場合とまったく同じです。SQLの設計者はWHERE、すべてを受け入れる場合でも、句を強制的に配置する代わりに句を指定しないという事実は、多かれ少なかれ構文上の砂糖であり、単純な利便性のためにそのオプションを提供しただけです。 ..
パンツァークライシス14

5
多くの場合、コードが呼び出しを必要とするかどうかを決定し、必要でない場合はスキップするよりも、コードが無条件に有用なことをする可能性のある仮想メソッドまたはデリゲートを呼び出す方が高速でクリーンであることは注目に値するかもしれません。
supercat 14

15

それは単なる多態性ではありませんか?

私のQt tr()wtr()メソッドの経験から、のテキストのローカライズには(Qtで)使用されることになっていWidgetます。

したがって、変更されていないテキストを返すことにより、このメソッドは次のように伝えますWidget does no localization (translation of the text) by default. Override this function to enable your own logic


1
これがQTのことだとは気づかなかった-これは明らかに答えだ。
コーリーブリグマン14

8

これに関する非常に一般的なケースは、「後で追加される機能」です。そのため、プログラマーは、後でその機能に何らかの変更が加えられる可能性があると考えました。パラメータ自体としてではなく、関数としてアクセスするため、これを簡単にグローバルに変更できます。次のようなインデックスがあるとします。

function getIndex(index)
    return index
end

インデックスは0から始まるため、これで十分です。後でコンポーネントを別の場所に変更した場合、このコンポーネントではインデックスを1から開始するように変換する必要があります。コードのどこにでも数百のインデックス+1を追加する必要があります。しかし、このような方法では、単に次のように言います。

 function getIndex(index)
    return index+1
end

元気です このような機能はすぐに過剰なエンジニアリングにつながる可能性がありますが、いくつかの点で非常に意味があります!


2
はい。ただし、OPによって投稿された関数のドクトストリングは、これが彼の場合の関数の目的であることを示唆していないことに注意する価値があります。
マークアメリー

6

このようなスタブ関数は、型継承の状況では一般的です。基本クラスは何の役にも立たないかもしれませんが、派生クラスは入力に対してさまざまなことをするかもしれません。基本クラスでスタブ関数を宣言すると、すべての派生クラスがその名前の関数を持つことができ、個々の派生クラスはより複雑で便利なものでそれをオーバーライドできます


5

追加のシナリオの1つは、PythonおよびプロパティのC#での使用に似ていますが、機能を持たない言語での使用です。

一般に、クラスのメンバーとして何かを宣言できます。文字列として「名前」としましょう。これは、次のようにアクセスすることを意味します。

someobject.name

後で、名前は実際にオブジェクトの内容に依存する必要があると判断します。だから、それは本当に関数でなければなりません。おっとっと!引数がなくても、アクセスするすべてのコードを次のように変更する必要があることを意味します

someobject.name()

ただし、この呼び出しのインスタンスが多数ある場合、何も問題が発生する可能性はかなり低くなります。この変更は行われず、その時点に達するとプログラムがクラッシュします。

C#/ Pythonのプロパティを使用すると、以前は属性であったものを関数で置き換えることができますが、属性のように、つまり変更なしでアクセスできます。前もって計画する必要さえありません。

あなたの言語にそれがない場合は、事前に計画する必要がありますが、最初から何もしない機能にすることで、以前のようにサポートすることができます。最初は、何も面白くなく、削除する必要があるように見えます。このタイプの多くの関数は変更されません。しかし、後で、実際に電話Widget.wtrするたびにいくつかの特殊文字を取り除く必要があることに気付いた場合、それは大したことではありません-それはすでに関数であり、それを追加するだけで完了です。

TL; DRこれは、将来の変更を前もって計画している賢明なプログラマーかもしれません。


3
この方法が他のものに依存している場合、それは理にかなっていますが、そうではありません。プロパティ、getter / setter、またはフィールドではありません。これは現在何もしないメソッドです。彼が将来の変更を計画しているのは、このメソッドのロジックを変更する必要がある場合のみです。
マシュースティープルズ14

1
する必要はありません...つまり、現時点ではこのデータを処理しませんが、後で処理したい場合は、そのデータのすべてのユーザーが処理済みのデータを無料で取得します。馬鹿げた例:画面に文字列を出力するとしましょうprint data。その後、すべての文字列を大文字にする必要があることに気付きます。プログラム内のすべてのプリントを見つけてに変更する必要がありprint data.upper()ます。しかし、あなたが持っていてdef cdata(data): return data、どこでも言うなら、あなたはprint cdata(data)ただ変更しdef cdata(data): return data.upper()、それが唯一の変更です。
コーリーブリグマン14

そこにあなたの意味がわかります。それはより理にかなっています
マシュースティープルズ14

2

無駄ではありません。実際、コードがより均一で柔軟になるため、非常に便利です。

たとえば、「すべて」または「男性」または「女性」のみを表示するかどうかを選択するためのユーザーのリストとドロップダウンがあるとします。

「すべて」を特別なケースとして処理することができます。この場合、追加のifとifを明示的に確認する必要があります。または、パラメーターを返すだけのフィルター関数を使用できます(たとえば、すべてを渡すことができます)。 「すべて」のケースに使用されるように割り当てられています。


4
それはシナリオに適合しません。私は彼のパラメーターを返す関数を意味し、いかなる場合でも、他に何もしません。
センピー14

@センピー:それは彼が言っていることです。サブクラスを持つFilterクラスまたはインターフェースがMaleFilterありFemaleFilter、コードにフィルターが必要な場合、何もしない(パラメーターを変更せずに戻す)フィルターが処理されAllます。この関数は何も実行しませんが、実行する関数に置き換えることができます。
メイガス14

@Magus、しかしあなたのシナリオでは、関数はある種のプレースホルダーであり、後で置換されるか、古い関数が廃止されたために存在するが、プログラムはこのパススルーを必要とします。とにかく、それは引き渡しではありません。この関数は、フィルターが行うように、変更されていないパラメーターを別の関数に渡しませんが、呼び出し元の関数に返します。
センピー14年

@Sempieいいえ、それは一時的なパススルーとして使用するのではなく、プレースホルダーでもありません。これは、有用なコーディング(および数学)概念である「アイデンティティ」機能です。そして、はい、それは「別の機能」または呼び出し機能にそれを返すかどうかにかかわらず、まだハンドオーバーです。重要なことは、「アイデンティティ」機能が呼び出し機能によって呼び出される多くの可能な機能の1つであり、使用されることです呼び出された関数が何もする必要がない場合のifと特別なケースを回避します。
ヘジャズマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.