Dartで可変数の引数またはパラメーターを使用して関数を作成する方法を探しています。代わりに配列パラメーターを作成できることはわかっていますが、構文の簡潔さが重要なライブラリーで作業しているため、作成したくないと思います。
たとえば、プレーンJavaScriptでは、次のようなことができます( here から借用):
function superHeroes() {
for (var i = 0; i < arguments.length; i++) {
console.log("There's no stopping " + arguments[i]);
}
}
superHeroes('UberMan', 'Exceptional Woman', 'The Hunk');
ただし、Dartでは、そのコードは実行されません。ダーツで同じことをする方法はありますか?そうでない場合、これはロードマップにあるものですか?
今のところそれはできません。
varargsが戻ってくるかどうかは本当にわかりません-数回前にありましたが 削除されました 。
ただし、varargsを 関数のエミュレート でエミュレートすることは可能です。以下のコードスニペットを参照してください。
typedef dynamic OnCall(List);
class VarargsFunction extends Function {
OnCall _onCall;
VarargsFunction(this._onCall);
call() => _onCall([]);
noSuchMethod(Invocation invocation) {
final arguments = invocation.positionalArguments;
return _onCall(arguments);
}
}
main() {
final superHeroes = new VarargsFunction((arguments) {
for (final superHero in arguments) {
print("There's no stopping ${superHero}");
}
});
superHeroes('UberMan', 'Exceptional Woman', 'The Hunk');
}
Alexandre Ardhuinの答えを少し試してみたところ、現在のバージョンのDartでこの作業を行うためにいくつかの調整ができることがわかりました。
_class VarArgsClass {
noSuchMethod(InvocationMirror invocation) {
if (invocation.memberName == 'superheroes') {
this.superheroes(invocation.positionalArguments);
}
}
void superheroes(List<String> heroNames) {
for (final superHero in heroNames) {
print("There's no stopping ${superHero}!");
}
}
}
main() {
new VarArgsClass().superheroes('UberMan', 'Exceptional Woman', 'The Hunk');
}
_
これには、次のような多くの問題があります。
superheroes()
を呼び出すと警告が生成されます。List<String>
_であることを確認するには、さらに手動でチェックする必要があります。noSuchMethod()
でメンバー名を確認する必要があると、メソッド名を変更した場合に「スーパーヒーロー」文字列を変更するのを忘れる可能性が高くなります。しかし、これらすべての問題に問題がなければ、これで作業は完了です。
構文の簡潔さに本当に興味がある場合は、たとえば10個のオプションの位置パラメーターを使用して関数/メソッドを宣言するだけです。誰かが10以上の引数でそれを呼び出すことはありそうにありません。
それがハックのように聞こえる場合、それはそれがisハックだからです。しかし、私はダートチームが同じことをしているのを見ました:-)
あなたが書いた例では、リストを使用するのが最善だと思います。すみません!
Dartbug.comを見ていますが、これに対する機能リクエストが表示されません。あなたは間違いなくそれを作成することを歓迎します!
このバージョン:
typedef T VarArgsCallback<T>(List<dynamic> args, Map<String, dynamic> kwargs);
class VarArgsFunction<T> {
final VarArgsCallback<T> callback;
static var _offset = 'Symbol("'.length;
VarArgsFunction(this.callback);
T call() => callback([], {});
@override
dynamic noSuchMethod(Invocation inv) {
return callback(
inv.positionalArguments,
inv.namedArguments.map(
(_k, v) {
var k = _k.toString();
return MapEntry(k.substring(_offset, k.length - 2), v);
},
),
);
}
}
main() {
dynamic myFunc = VarArgsFunction((args, kwargs) {
print('Got args: $args, kwargs: $kwargs');
});
myFunc(1, 2, x: true, y: false); // Got args: [1, 2], kwargs: {x: true, y: false}
}
ありがとう、アレクサンドル answer !