0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dart/flutter でオプショナル引数と名前付き引数を共存させる

Last updated at Posted at 2025-04-18

dart で可変長引数を実現するためのパッケージ(dynamic_function)を作成しました。

そのことは以下の記事で紹介しましたが、DynamicFunction では名前付き引数もサポートされます。

例えば、以下のような(オプショナル引数と名前付き引数を共存させる)定義は dart3 ではできません。
GitHub の issue もご覧ください:

以下の例では x が必須の positional parameter で title がオプショナル引数、そして asJson が名前付き引数です。

void echo(dynamic x, [String? title], {bool? asJson}) {
}

DynamicFunction を使えば、「オプショナル引数と名前付き引数を共存させる」ことができます。
デモソースの実行結果では、asJson を指定したときに「abc」ではなくて「"abc"」とダブルクォートがついていることに留意してください。

とりあえず、デモ用のソースを提示しておきます(dart-sdk-3.7.2 と dart-sdk-3.9.0-14.0.dev で動作を確認しました。また flutter web, flutter windows desktop でも動作しました(flutter-sdk-3.29.3))。

pubspec..yaml
name: qiita
description: A sample command-line application
version: 0.0.1
publish_to: none

environment:
  sdk: ^3.7.2

dependencies:
  dynamic_function: ^1.0.4

dev_dependencies:
named_demo.dart
import 'package:dynamic_function/dynamic_function.dart';
import 'dart:convert' as convert;

// void echo(dynamic x, [String? title], {bool? asJson});
// を目指しています
final dynamic echo = DynamicFunction((
  List<dynamic> positional,
  Map<Symbol, dynamic> named,
) {
  if (positional.length < 1 || positional.length > 2) {
    throw '${positional.length} arguments supplied to echo()';
  }
  dynamic x = positional[0];
  String? title = positional.length == 2 ? positional[1] as String : null;
  checkNamed(named, ['asJson']);
  bool asJson =
      named[Symbol('asJson')] == null ? false : named[Symbol('asJson')] as bool;
  String json = (x is String) ? '`${x}`' : '${x}';
  if (asJson) {
    json = convert.jsonEncode(x);
  }
  if (title == null) {
    print(json);
  } else {
    print('${title} ==> ${json}');
  }
  return null;
});

void main() {
  final x = [11, null, 'abc'];
  echo(x); // (1)
  echo(x, 'x'); // (2)
  echo(x, asJson: true); // (3)
  echo(x, 'x', asJson: true); // (4)
  //echo(); // 0 arguments supplied to echo()
  //echo(x, 'x', 777); // 3 arguments supplied to echo()
}

/*
【実行結果】
[11, null, abc] // (1)
x ==> [11, null, abc] // (2)
[11,null,"abc"] // (3)
x ==> [11,null,"abc"] // (4)
 */

どうです。おもしろいでしょう?
ちなみに、

checkNamed(named, ['asJson']);

というのは、オプショナルな名前付き引数の名前のリストを第二引数に指定して間違った名前付き引数が指定された場合に例外を投げてくれます。

checkNamed(named, ['asJson'], ['requiredParam']);

とすると、'requiredParam' は必須の名前付き引数としてチェックされます。

不明な点があればコメントでどうぞ!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?