何が入れ子機?今回展示されていたのですか?
-
22-08-2019 - |
質問
私は利用したことのない入れ子の機能は、参照の複数の言語と入れ子のクラスは、いい関係).
- 何が入れ子で機能しているのでしょうか。
- なぜなのか?!?
- でどこまでできる入れ子の機能を実行できないその他。
- でどこまでできる入れ子の機能この在り方に関する研究inelegantなく入れ子機?
い入れ子の機能だけでな案件を処理するものとして、オブジェクトの場合オブジェクトを含むその他のオブジェでおります。
い入れ子の機能の範囲(一般的だと思うので言語が異なること)を変数としての内部に機能してい範囲?
追記してください言語をご参照くあるご回答は言語agnostic.
-アダム
解決
ネストされた関数の1つの一般的使用は閉鎖です。ファーストクラスの機能を備えたレキシカルスコープの言語では、それはですデータを格納するための機能を使用することが可能。 Schemeでは簡単な例は、カウンタです。
(define (make-counter)
(let ((count 0)) ; used to store the count
(define (counter) ; this is the counter we're creating
(set! count (+ count 1)) ; increment the count
count) ; return the new count
counter)) ; return the new counter function
(define mycounter (make-counter)) ; create a counter called mycounter
(mycounter) ; returns 1
(mycounter) ; returns 2
この例では、私たちの巣機能カウンタ機能のメイクカウンターの内側、そして我々はそれが定義されたときに対抗するために利用可能なデータにアクセスすることができ、この内部関数を返すこともできます。この情報はmycounterのこのインスタンスにプライベートです - 私たちは別のカウンタを作成した場合、それは内部カウントを保存するために別の場所を使用します。前の例から続けます:
(define mycounter2 (make-counter))
(mycounter2) ; returns 1
(mycounter) ; returns 3
他のヒント
これは、再帰のために便利です。
string[] GetFiles(string path)
{
void NestedGetFiles(string path, List<string> result)
{
result.AddRange( files in the current path);
foreach(string subPath in FoldersInTheCurrentPath)
NestedGetFiles(subPath, result);
}
List<string> result = new List<string>();
NestedGetFiles(path, result);
return result.ToArray();
}
上記のコードは、完全に構成されていますが、私は何を意味するかのアイデアを与えるためにC#に基づいています。 NestedGetFilesを呼び出すことができる唯一の方法は、GetFilesメソッドです。
ネストされた関数は別の関数内だけの関数である。
はい、それはすべてが対象であることの結果です。あなたは、関数のスコープ内の変数にのみ表示することができ、および変数は関数を指すことができますので、あなたはローカル変数によって参照されている機能を持つことができます。
私はあなたが絶対になくてはならない可能性があり、ネストされた機能で何かできることはないと思います。多くの時間は、それはしかし、理にかなっています。すなわち、いつでも機能は、いくつかの他の機能の「サブ関数」である。
機能は、複雑なロジックの多くを実行しますが、どのような機能が/リターンを計算するロジックによって決定されるすべてのケースの抽象に簡単であるとき、私のための一般的なユースケースがある。
(Cの#): 私は、オブジェクトブラウザビューを簡素化するために、より良い私のクラスを構築するためにそれを使用します。 クラスのホイールは、トラッククラスで入れ子になったよう。
この詳細を忘れないでください: 「ネストした型は、任意の継承されたプライベートまたは保護されたメンバーを含む、含むタイプのプライベートおよびプロテクトメンバーにアクセスすることができます。」
ネストされた関数は、まだあなたが読みやすさや一般化のためにそのコードを分離できるようにしながらあなたは、その関数内の一つの機能の内部動作にのみ関連したコードをカプセル化することができます。いくつかの実装では、彼らはまた、外側のスコープへのアクセスを許可します。 Dで
int doStuff() {
int result;
void cleanUpReturn() {
myResource1.release();
myResource2.release();
return result * 2 + 1;
}
auto myResource1 = getSomeResource();
auto myResource2 = getSomeOtherResource();
if(someCondition) {
return cleanUpReturn();
} else {
doSomeOtherStuff();
return cleanUpReturn();
}
}
もちろん、この場合には、これはまた、RAIIで扱うことができますが、それは単純な例です。
にも役立ちます。彼らはまた、(Pythonで)ファクトリ関数のためのファクトリ関数を作るために役立つことができます:
>>> def GetIntMaker(x):
... def GetInt():
... return x
... return GetInt
...
>>> GetInt = GetIntMaker(1)
>>> GetInt()
1
ネストされた関数は、単に別の関数の本体内で定義された関数です。どうして?私は私の頭の上から考えることができる唯一の理由について、ヘルパーやユーティリティ関数です。
これは私と一緒に不自然な例が、クマです。あなたは結果の2つのクエリに基づいて行動し、クエリのいずれかの値を持つオブジェクトを埋めるために持っていた機能を持っていたとしましょう。あなたは、次のようなものを行うことができます。
function process(qryResult q1, qryResult q2) {
object o;
if (q1.someprop == "useme") {
o.prop1 = q1.prop1;
o.prop2 = q1.prop2;
o.prop3 = q1.prop3;
} else if (q2.someprop == "useme") {
o.prop1 = q2.prop1;
o.prop2 = q2.prop2;
o.prop3 = q2.prop3;
}
return o;
}
あなたは20個の特性を持っていた場合は、、あなたは上で、巨大な機能につながるの上にオブジェクトを設定するためのコードを複製しています。あなたは、オブジェクトへのクエリからのプロパティのコピーを行うには、単純なネストされた関数を追加することができます。このように:
function process(qryResult q1, qryResult q2) {
object o;
if (q1.someprop == "useme") {
fillObject(o,q1);
} else if (q2.someprop == "useme") {
fillObject(o,q2);
}
return o;
function fillObject(object o, qryResult q) {
o.prop1 = q.prop1;
o.prop2 = q.prop2;
o.prop3 = q.prop3;
}
}
これは、物事少しクリーナーを保持します。それは、ネストされた関数でなければなりませんか?処理機能は、このコピーを行う必要があります唯一のものである場合はありませんが、あなたは、このようにそれをやってみたいことがあります。