43

Dart で可変数の引数またはパラメーターを持つ関数を作成する方法を探しています。代わりに配列パラメーターを作成できることはわかっていますが、構文の簡潔さが重要なライブラリで作業しているため、そうしないことをお勧めします。

たとえば、プレーンな JavaScript では、次のようなことができます (ここから借用):

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 では、そのコードは実行されません。ダーツで同じことをする方法はありますか? そうでない場合、これはロードマップにあるものですか?

4

6 に答える 6

38

今のところ、それはできません。

varargsが戻ってくるかどうかはよくわかりません。以前はありましたが、削除されました。

ただし、エミュレート関数を使用して可変引数をエミュレートすることは可能です。以下のコード スニペットを参照してください。

typedef OnCall = dynamic Function(List arguments);

class VarargsFunction {
  VarargsFunction(this._onCall);
  
  final OnCall _onCall;

  noSuchMethod(Invocation invocation) {
    if (!invocation.isMethod || invocation.namedArguments.isNotEmpty)
      super.noSuchMethod(invocation);
    final arguments = invocation.positionalArguments;
    return _onCall(arguments);
  }
}

main() {
  final superHeroes = VarargsFunction((arguments) {
    for (final superHero in arguments) {
      print("There's no stopping ${superHero}");
    }
  }) as dynamic;
  superHeroes('UberMan', 'Exceptional Woman', 'The Hunk');
}
于 2012-12-05T21:07:15.440 に答える
7

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()あると、メソッド名を変更した場合に「スーパーヒーロー」文字列を変更するのを忘れる可能性が高くなります。
  • リフレクションは、コード パスの追跡を困難にします。

しかし、これらすべての問題に問題がなければ、これで作業は完了です。

于 2012-12-05T23:17:03.023 に答える
3

本当に構文を簡潔にしたい場合は、たとえば 10 個のオプションの位置パラメーターを使用して関数/メソッドを宣言するだけで完了です。誰かが 10 以上の引数でそれを呼び出す可能性は低いです。

ハックのように聞こえる場合、それハックだからです。しかし、私は Dart チームが同じことをしているのを見てきました :-)

:

void someMethod(arg0, [arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9]) {
  final args = [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9];

  args.removeWhere((value) => value == null);

  /* do something the the args List */
  print(args);
}
于 2012-12-06T05:21:58.760 に答える
2

あなたが書いた例については、リストを使用するのが最善だと思います。ごめんなさい!

dartbug.com を見ていますが、これに関する機能のリクエストがありません。あなたは間違いなくそれを作成することを歓迎します!

于 2012-12-05T23:01:13.123 に答える