Re: 関数への参照を渡すことは可能ですか?参照によって渡す簡単な方法はありませんが、関数とデータをクラスまたは名前空間にカプセル化し、オブジェクト ポインターまたは名前空間名を渡すことができます。 上部の写真を見てくださいJSLオブジェクトを使用した関数型プログラミングそれがクラスにどのように役立つかを知るためです。
Re: 関数への参照を渡すことは可能ですか?私はこのようなものをよく使います。私の経験から、 NameExpr()機能は非常にうまく機能します。関数を別の関数から返すときは注意が必要です。 @Craige_Hales通常は、この方法の方が良い選択です。
私は Qt の幅広いバックグラウンドを持っており、それらのシグナル/スロットを本当に高く評価しています - 私は JSL で非常によく似たものを作成しました。参照によって関数をシャトルする必要があり、名前空間/クラス ラッパーでそれを行うのはあまり実用的ではないので、私は非常に何かを使用しますこれに似ています。
someFunc = Function( {arg},
{},
Print( "Within One Function" );
Print( arg );
);
executor = Function( {fn, arg},
{},
Print( "Executing..." );
fn( arg );
);
executor( Name Expr( someFunc ), "this string" )Re: 関数への参照を渡すことは可能ですか?そのほうがシンプルで理解しやすいように見えます。 頻繁に呼び出される大規模な関数の場合にのみ違いが生じるトレードオフがあります。 NameExpr は関数の式ツリーを複製し、参照ではなくコピーを渡します。 タイミングを計る以外に、コピーか参照かを判断する方法はないと思います(戻り時に変更されない配列の場合と同様)。
loops=1e5; // ~10 seconds/100K loops
print = (loops==1e0);
someFunc = Function( {arg}, {},
If( print,
Print( "Within One Function" );
Print( arg );
);
Return( 0 );
// this creates a stiff penalty for nameexpr
// needing to clone this function. These
// statements are simple and never executed but still
// must be copied to the nameExpr result by allocating
// a bunch of memory objects.
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
);
/////////////////////////////////////
Write( "\!nUsing NameExpr" );
executor = Function( {fn, arg}, {},
If( print,
Print( "Executing for NameExpr..." )
);
fn( arg );
);
start = HP Time();
For( i = 1, i <= loops, i += 1,
executor( Name Expr( someFunc ), "this string" )
);
stop = HP Time();
Show( stop - start ); // ~7 seconds
/////////////////////////////////////
Write( "\!nUsing class" );
Define Class(
"PassByRef",
mFn = .;
_init_ = Method( {fn},
mFn = Name Expr( fn )
);
);
// grab the identical function into a reference object >>>>> requires JMP 17, a bug was fixed after 16.2
somefuncRef = New Object( PassByRef( Name Expr( someFunc ) ) );
<BR />/* for JMP < 17 use this work-around: <BR />somefuncRef = New Object( PassByRef( 0 ) );<BR />somefuncRef:mFn=Name Expr( someFunc );<BR />*/
/********** this also works and looks ... better?
somefuncRef = New Object( PassByRef( Function( {arg}, {},
If( print,
Print( "Within One Function" );
Print( arg );
);
Return( 0 );
// this creates a stiff penalty for nameexpr
// needing to clone this function. These
// statements are simple and never executed but still
// must be copied to the nameExpr result by allocating
// a bunch of memory objects.
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
);
));
*********/
executor = Function( {fnRef, arg}, {},
If( print,
Print( "Executing for class..." )
);
fnRef:mFn( arg );
);
start = HP Time();
For( i = 1, i <= loops, i += 1,
executor( somefuncRef, "this string" )
);
stop = HP Time();
Show( stop - start ); // ~3 seconds
大規模な関数の最大 2 倍のパフォーマンス向上は、0;0;0; として消滅します。ダミーステートメントは削除されます。 Qt のような方法で使用している短い関数の場合は、違いはありません。
関数への参照を渡すことは可能ですか?たとえば、このスクリプトを実行すると、次のようになります。
someFunc = Function( {arg},
{},
Print( arg );
);
executor = Function( {fn, arg},
{},
fn( arg );
);
executor( someFunc, "this string" )エラーが発生しました。これは、実行プログラムへの参照を渡そうとしているときに someFunc を呼び出していることを意味しているようです。
呼び出しで関数を定義することで参照を渡すことができます。
executor = Function( {fn, arg},
{},
Print(arg);
fn();
);
executor( Function({}, {}, Print("anonymous function"); ), "wut" );出力:
"wut"
"anonymous function"
これで必要なことは実現できますが、変数名を使用して関数を渡せると便利です。
高度な統計モデリング自動化とスクリプト作成消費者および市場調査品質およびプロセスエンジニアリングRe: 関数への参照を渡すことは可能ですか?に関するさらなるドキュメントはどこで見つかりますか? PassByRefオプション?
ああ。
Re: 関数への参照を渡すことは可能ですか?@ホギ- 申し訳ありませんが、コードの途中に重要な部分を埋めてしまいました。 他の人にとっても、
Define Class(
"PassByRef",
mFn = .;
_init_ = Method( {fn},
mFn = Name Expr( fn )
);
);
somefuncRef = New Object( PassByRef( Name Expr( someFunc ) ) );
という名前のクラス定義を作成していますPassByRefそしてそのクラスのインスタンスの名前はある機能参照。 インスタンスは mFn のラッパーであり、mFn のクローンを保持します。いくつかの機能。 ただし、そのクローンは、さらにクローンを作成することなく、何度も再利用されます。 執行者はここで呼び出しを行います
executor = Function( {fnRef, arg}, {},
If( print,
Print( "Executing for class..." )
);
fnRef:mFn( arg );
);