メインコンテンツにスキップ

dart:core

dart:core ライブラリ (APIリファレンス) は、小さながらも重要な組み込み機能セットを提供します。このライブラリは、すべてのDartプログラムに自動的にインポートされます。

コンソールへの出力

#

トップレベルのprint()メソッドは、単一の引数 (任意のObject) を取り、そのオブジェクトの文字列値 (toString()によって返される) をコンソールに表示します。

dart
print(anObject);
print('I drink $tea.');

基本的な文字列とtoString()に関する詳細は、言語ツアーの文字列を参照してください。

数値

#

dart:core ライブラリは、数値の操作に関する基本的なユーティリティを持つ num、int、double クラスを定義しています。

それぞれ、int と double の parse() メソッドを使用して、文字列を整数または浮動小数点数に変換できます。

dart
assert(int.parse('42') == 42);
assert(int.parse('0x42') == 66);
assert(double.parse('0.50') == 0.5);

または、可能な場合は整数を、それ以外の場合は浮動小数点数を作成する num の parse() メソッドを使用します。

dart
assert(num.parse('42') is int);
assert(num.parse('0x42') is int);
assert(num.parse('0.50') is double);

整数の基数を指定するには、radix パラメータを追加します。

dart
assert(int.parse('42', radix: 16) == 66);

toString() メソッドを使用して、int または double を文字列に変換します。小数点以下の桁数を指定するには、toStringAsFixed() を使用します。文字列の有効桁数を指定するには、toStringAsPrecision() を使用します。

dart
// Convert an int to a string.
assert(42.toString() == '42');

// Convert a double to a string.
assert(123.456.toString() == '123.456');

// Specify the number of digits after the decimal.
assert(123.456.toStringAsFixed(2) == '123.46');

// Specify the number of significant figures.
assert(123.456.toStringAsPrecision(2) == '1.2e+2');
assert(double.parse('1.2e+2') == 120.0);

詳細については、int、 double、 および num のAPIドキュメントを参照してください。また、dart:math セクションも参照してください。

文字列と正規表現

#

Dart における文字列は、UTF-16 コードユニットの不変シーケンスです。言語ツアーには、文字列に関する詳細情報があります。正規表現 (RegExp オブジェクト) を使用して、文字列内を検索したり、文字列の一部を置換したりできます。

String クラスは、split()contains()startsWith()endsWith() などのメソッドを定義しています。

文字列内の検索

#

文字列内の特定の場所を見つけたり、文字列が特定のパターンで始まるか終わるかを確認したりできます。例:

dart
// Check whether a string contains another string.
assert('Never odd or even'.contains('odd'));

// Does a string start with another string?
assert('Never odd or even'.startsWith('Never'));

// Does a string end with another string?
assert('Never odd or even'.endsWith('even'));

// Find the location of a string inside a string.
assert('Never odd or even'.indexOf('odd') == 6);

文字列からのデータ抽出

#

文字列から個々の文字を、それぞれ文字列または整数として取得できます。正確には、UTF-16 コードユニットを取得します。高位の文字 (例: トレブルクレフ記号 ('\u{1D11E}')) は、それぞれ 2 つのコードユニットです。

部分文字列を抽出したり、文字列を部分文字列のリストに分割したりすることもできます。

dart
// Grab a substring.
assert('Never odd or even'.substring(6, 9) == 'odd');

// Split a string using a string pattern.
var parts = 'progressive web apps'.split(' ');
assert(parts.length == 3);
assert(parts[0] == 'progressive');

// Get a UTF-16 code unit (as a string) by index.
assert('Never odd or even'[0] == 'N');

// Use split() with an empty string parameter to get
// a list of all characters (as Strings); good for
// iterating.
for (final char in 'hello'.split('')) {
  print(char);
}

// Get all the UTF-16 code units in the string.
var codeUnitList = 'Never odd or even'.codeUnits.toList();
assert(codeUnitList[0] == 78);

::: 多くの場合、純粋なコードユニットではなく、Unicode グラフェムクラスターを扱いたい場合があります。これらはユーザーが知覚する文字です (例: 「🇬🇧」はユーザーが知覚する 1 文字ですが、UTF-16 コードユニットは複数です)。この目的のために、Dart チームは characters パッケージを提供しています。 ::

大文字・小文字への変換

#

文字列を大文字または小文字のバリアントに簡単に変換できます。

dart
// Convert to uppercase.
assert('web apps'.toUpperCase() == 'WEB APPS');

// Convert to lowercase.
assert('WEB APPS'.toLowerCase() == 'web apps');

トリミングと空文字列

#

trim() を使用して、すべての先頭と末尾の空白を削除します。文字列が空 (長さがゼロ) かどうかを確認するには、isEmpty を使用します。

dart
// Trim a string.
assert('  hello  '.trim() == 'hello');

// Check whether a string is empty.
assert(''.isEmpty);

// Strings with only white space are not empty.
assert('  '.isNotEmpty);

文字列の一部置換

#

文字列は不変オブジェクトであるため、作成はできますが変更することはできません。 String API リファレンスをよく見ると、メソッドのいずれも String の状態を変更していないことに気付くでしょう。たとえば、replaceAll() メソッドは、元の String を変更せずに新しい String を返します。

dart
var greetingTemplate = 'Hello, NAME!';
var greeting = greetingTemplate.replaceAll(RegExp('NAME'), 'Bob');

// greetingTemplate didn't change.
assert(greeting != greetingTemplate);

文字列の構築

#

プログラムで文字列を生成するには、StringBuffer を使用できます。StringBuffer は、toString() が呼び出されるまで新しい String オブジェクトを生成しません。writeAll() メソッドには、区切り文字 (この場合はスペース) を指定できるオプションの 2 番目のパラメータがあります。

dart
var sb = StringBuffer();
sb
  ..write('Use a StringBuffer for ')
  ..writeAll(['efficient', 'string', 'creation'], ' ')
  ..write('.');

var fullString = sb.toString();

assert(fullString == 'Use a StringBuffer for efficient string creation.');

正規表現

#

RegExp クラスは、JavaScript の正規表現と同じ機能を提供します。正規表現を使用して、文字列の効率的な検索とパターンマッチングを行います。

dart
// Here's a regular expression for one or more digits.
var digitSequence = RegExp(r'\d+');

var lettersOnly = 'llamas live fifteen to twenty years';
var someDigits = 'llamas live 15 to 20 years';

// contains() can use a regular expression.
assert(!lettersOnly.contains(digitSequence));
assert(someDigits.contains(digitSequence));

// Replace every match with another string.
var exedOut = someDigits.replaceAll(digitSequence, 'XX');
assert(exedOut == 'llamas live XX to XX years');

RegExp クラスを直接操作することもできます。Match クラスは、正規表現のマッチへのアクセスを提供します。

dart
var digitSequence = RegExp(r'\d+');
var someDigits = 'llamas live 15 to 20 years';

// Check whether the reg exp has a match in a string.
assert(digitSequence.hasMatch(someDigits));

// Loop through all matches.
for (final match in digitSequence.allMatches(someDigits)) {
  print(match.group(0)); // 15, then 20
}

詳細情報

#

メソッドの完全なリストについては、String API リファレンスを参照してください。また、StringBuffer、 Pattern、 RegExp、 および Match のAPIリファレンスも参照してください。

コレクション

#

Dart には、リスト、セット、マップ用のクラスを含むコアコレクション API が付属しています。

リスト

#

言語ツアーで示されているように、リテラルを使用して リストを作成および初期化できます。または、List コンストラクタのいずれかを使用します。List クラスは、リストにアイテムを追加したり削除したりするためのいくつかのメソッドも定義しています。

dart
// Create an empty list of strings.
var grains = <String>[];
assert(grains.isEmpty);

// Create a list using a list literal.
var fruits = ['apples', 'oranges'];

// Add to a list.
fruits.add('kiwis');

// Add multiple items to a list.
fruits.addAll(['grapes', 'bananas']);

// Get the list length.
assert(fruits.length == 5);

// Remove a single item.
var appleIndex = fruits.indexOf('apples');
fruits.removeAt(appleIndex);
assert(fruits.length == 4);

// Remove all elements from a list.
fruits.clear();
assert(fruits.isEmpty);

// You can also create a List using one of the constructors.
var vegetables = List.filled(99, 'broccoli');
assert(vegetables.every((v) => v == 'broccoli'));

リスト内のオブジェクトのインデックスを見つけるには、indexOf() を使用します。

dart
var fruits = ['apples', 'oranges'];

// Access a list item by index.
assert(fruits[0] == 'apples');

// Find an item in a list.
assert(fruits.indexOf('apples') == 0);

sort() メソッドを使用してリストをソートします。2 つのオブジェクトを比較するソート関数を提供できます。このソート関数は、小さい場合は < 0、同じ場合は 0、大きい場合は > 0 を返す必要があります。次の例では、Comparable によって定義され、String によって実装される compareTo() を使用しています。

dart
var fruits = ['bananas', 'apples', 'oranges'];

// Sort a list.
fruits.sort((a, b) => a.compareTo(b));
assert(fruits[0] == 'apples');

リストはパラメータ化された型 (ジェネリクス) であるため、リストが含むべき型を指定できます。

dart
// This list should contain only strings.
var fruits = <String>[];

fruits.add('apples');
var fruit = fruits[0];
assert(fruit is String);
✗ 静的解析: 失敗dart
fruits.add(5); // Error: 'int' can't be assigned to 'String'

メソッドの完全なリストについては、List API リファレンスを参照してください。

セット

#

Dart のセットは、一意なアイテムの順序付けられていないコレクションです。セットは順序付けられていないため、インデックス (位置) でセットのアイテムを取得することはできません。

dart
// Create an empty set of strings.
var ingredients = <String>{};

// Add new items to it.
ingredients.addAll(['gold', 'titanium', 'xenon']);
assert(ingredients.length == 3);

// Adding a duplicate item has no effect.
ingredients.add('gold');
assert(ingredients.length == 3);

// Remove an item from a set.
ingredients.remove('gold');
assert(ingredients.length == 2);

// You can also create sets using
// one of the constructors.
var atomicNumbers = Set.from([79, 22, 54]);

セットに 1 つ以上のオブジェクトが含まれているかどうかを確認するには、contains()containsAll() を使用します。

dart
var ingredients = Set<String>();
ingredients.addAll(['gold', 'titanium', 'xenon']);

// Check whether an item is in the set.
assert(ingredients.contains('titanium'));

// Check whether all the items are in the set.
assert(ingredients.containsAll(['titanium', 'xenon']));

共通集合は、2 つの他のセットのアイテムが含まれるセットです。

dart
var ingredients = Set<String>();
ingredients.addAll(['gold', 'titanium', 'xenon']);

// Create the intersection of two sets.
var nobleGases = Set.from(['xenon', 'argon']);
var intersection = ingredients.intersection(nobleGases);
assert(intersection.length == 1);
assert(intersection.contains('xenon'));

メソッドの完全なリストについては、Set API リファレンスを参照してください。

マップ

#

マップは、一般的に辞書またはハッシュとして知られており、キーと値のペアの順序付けられていないコレクションです。マップは、キーを値に関連付けて簡単に取得できるようにします。JavaScript とは異なり、Dart オブジェクトはマップではありません。

簡潔なリテラル構文を使用してマップを宣言することも、従来のコンストラクタを使用することもできます。

dart
// Maps often use strings as keys.
var hawaiianBeaches = {
  'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'],
  'Big Island': ['Wailea Bay', 'Pololu Beach'],
  'Kauai': ['Hanalei', 'Poipu'],
};

// Maps can be built from a constructor.
var searchTerms = Map();

// Maps are parameterized types; you can specify what
// types the key and value should be.
var nobleGases = Map<int, String>();

ブラケット構文を使用してマップアイテムを追加、取得、設定します。マップからキーとその値 を削除するには、remove() を使用します。

dart
var nobleGases = {54: 'xenon'};

// Retrieve a value with a key.
assert(nobleGases[54] == 'xenon');

// Check whether a map contains a key.
assert(nobleGases.containsKey(54));

// Remove a key and its value.
nobleGases.remove(54);
assert(!nobleGases.containsKey(54));

マップからすべての値またはすべてのキーを取得できます。

dart
var hawaiianBeaches = {
  'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'],
  'Big Island': ['Wailea Bay', 'Pololu Beach'],
  'Kauai': ['Hanalei', 'Poipu'],
};

// Get all the keys as an unordered collection
// (an Iterable).
var keys = hawaiianBeaches.keys;

assert(keys.length == 3);
assert(Set.from(keys).contains('Oahu'));

// Get all the values as an unordered collection
// (an Iterable of Lists).
var values = hawaiianBeaches.values;
assert(values.length == 3);
assert(values.any((v) => v.contains('Waikiki')));

マップにキーが含まれているかどうかを確認するには、containsKey() を使用します。マップの値は null になる可能性があるため、キーの存在を判断するために、単にキーの値を取得して null をチェックするだけでは不十分です。

dart
var hawaiianBeaches = {
  'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'],
  'Big Island': ['Wailea Bay', 'Pololu Beach'],
  'Kauai': ['Hanalei', 'Poipu'],
};

assert(hawaiianBeaches.containsKey('Oahu'));
assert(!hawaiianBeaches.containsKey('Florida'));

マップにキーが存在しない場合にのみキーに値を割り当てたい場合は、putIfAbsent() メソッドを使用します。値を返す関数を提供する必要があります。

dart
var teamAssignments = <String, String>{};
teamAssignments.putIfAbsent('Catcher', () => pickToughestKid());
assert(teamAssignments['Catcher'] != null);

メソッドの完全なリストについては、Map API リファレンスを参照してください。

一般的なコレクションメソッド

#

List、Set、Map は、多くのコレクションで見られる共通の機能 を共有しています。これらの共通機能の一部は、List と Set が実装する Iterable クラスによって定義されています。

リスト、セット、またはマップにアイテムがあるかどうかを確認するには、isEmpty または isNotEmpty を使用します。

dart
var coffees = <String>[];
var teas = ['green', 'black', 'chamomile', 'earl grey'];
assert(coffees.isEmpty);
assert(teas.isNotEmpty);

リスト、セット、またはマップの各アイテムに関数を適用するには、forEach() を使用できます。

dart
var teas = ['green', 'black', 'chamomile', 'earl grey'];

teas.forEach((tea) => print('I drink $tea'));

マップで forEach() を呼び出す場合、関数は 2 つの引数 (キーと値) を取る必要があります。

dart
hawaiianBeaches.forEach((k, v) {
  print('I want to visit $k and swim at $v');
  // I want to visit Oahu and swim at
  // [Waikiki, Kailua, Waimanalo], etc.
});

Iterable は map() メソッドを提供しており、これにより、すべての結果を 1 つのオブジェクトで取得できます。

dart
var teas = ['green', 'black', 'chamomile', 'earl grey'];

var loudTeas = teas.map((tea) => tea.toUpperCase());
loudTeas.forEach(print);

関数が各アイテムに対してすぐに呼び出されるようにするには、map().toList() または map().toSet() を使用します。

dart
var loudTeas = teas.map((tea) => tea.toUpperCase()).toList();

Iterable の where() メソッドを使用して、条件に一致するすべてのアイテムを取得します。Iterable の any() および every() メソッドを使用して、一部またはすべてのアイテムが条件に一致するかどうかを確認します。

dart
var teas = ['green', 'black', 'chamomile', 'earl grey'];

// Chamomile is not caffeinated.
bool isDecaffeinated(String teaName) => teaName == 'chamomile';

// Use where() to find only the items that return true
// from the provided function.
var decaffeinatedTeas = teas.where((tea) => isDecaffeinated(tea));
// or teas.where(isDecaffeinated)

// Use any() to check whether at least one item in the
// collection satisfies a condition.
assert(teas.any(isDecaffeinated));

// Use every() to check whether all the items in a
// collection satisfy a condition.
assert(!teas.every(isDecaffeinated));

メソッドの完全なリストについては、Iterable API リファレンス、および List、 Set、 および Map の API リファレンスを参照してください。

URI

#

Uri クラスは、URI (URL としても知られています) で使用する文字列をエンコードおよびデコードするための関数を提供します。これらの関数は、URI にとって特別な文字 (& や = など) を処理します。Uri クラスは、URI のコンポーネント (ホスト、ポート、スキームなど) を解析して公開します。

完全修飾URIのエンコードとデコード

#

URI で特別な意味を持つ文字 (「/」、「:」、「&」、「#」など) を除く文字をエンコードおよびデコードするには、encodeFull() および decodeFull() メソッドを使用します。これらのメソッドは、完全修飾 URI のエンコードまたはデコードに便利で、特別な URI 文字をそのまま残します。

dart
var uri = 'https://example.org/api?foo=some message';

var encoded = Uri.encodeFull(uri);
assert(encoded == 'https://example.org/api?foo=some%20message');

var decoded = Uri.decodeFull(encoded);
assert(uri == decoded);

somemessage の間のスペースのみがエンコードされていることに注意してください。

URIコンポーネントのエンコードとデコード

#

URI で特別な意味を持つ文字列のすべての文字 (「/」、「&」、「:」など、これらに限定されません) をエンコードおよびデコードするには、encodeComponent() および decodeComponent() メソッドを使用します。

dart
var uri = 'https://example.org/api?foo=some message';

var encoded = Uri.encodeComponent(uri);
assert(
  encoded == 'https%3A%2F%2Fexample.org%2Fapi%3Ffoo%3Dsome%20message',
);

var decoded = Uri.decodeComponent(encoded);
assert(uri == decoded);

すべての特殊文字がエンコードされていることに注意してください。たとえば、「/」は「%2F」にエンコードされます。

URIの解析

#

Uri オブジェクトまたは URI 文字列がある場合、path などの Uri フィールドを使用してその部分を取得できます。文字列から Uri を作成するには、parse() 静的メソッドを使用します。

dart
var uri = Uri.parse('https://example.org:8080/foo/bar#frag');

assert(uri.scheme == 'https');
assert(uri.host == 'example.org');
assert(uri.path == '/foo/bar');
assert(uri.fragment == 'frag');
assert(uri.origin == 'https://example.org:8080');

取得できるその他の URI コンポーネントについては、Uri API リファレンスを参照してください。

URIの構築

#

Uri() コンストラクタを使用して、個々の部分から URI を構築できます。

dart
var uri = Uri(
  scheme: 'https',
  host: 'example.org',
  path: '/foo/bar',
  fragment: 'frag',
  queryParameters: {'lang': 'dart'},
);
assert(uri.toString() == 'https://example.org/foo/bar?lang=dart#frag');

フラグメントを指定する必要がない場合は、http または https スキームを持つ URI を作成するために、代わりに Uri.http または Uri.https ファクトリコンストラクタを使用できます。

dart
var httpUri = Uri.http('example.org', '/foo/bar', {'lang': 'dart'});
var httpsUri = Uri.https('example.org', '/foo/bar', {'lang': 'dart'});

assert(httpUri.toString() == 'http://example.org/foo/bar?lang=dart');
assert(httpsUri.toString() == 'https://example.org/foo/bar?lang=dart');

日付と時刻

#

DateTime オブジェクトは、ある時点を表します。タイムゾーンは UTC またはローカルタイムゾーンです。

いくつかのコンストラクタとメソッドを使用して DateTime オブジェクトを作成できます。

dart
// Get the current date and time.
var now = DateTime.now();

// Create a new DateTime with the local time zone.
var y2k = DateTime(2000); // January 1, 2000

// Specify the month and day.
y2k = DateTime(2000, 1, 2); // January 2, 2000

// Specify the date as a UTC time.
y2k = DateTime.utc(2000); // 1/1/2000, UTC

// Specify a date and time in ms since the Unix epoch.
y2k = DateTime.fromMillisecondsSinceEpoch(946684800000, isUtc: true);

// Parse an ISO 8601 date in the UTC time zone.
y2k = DateTime.parse('2000-01-01T00:00:00Z');

// Create a new DateTime from an existing one, adjusting just some properties:
var sameTimeLastYear = now.copyWith(year: now.year - 1);

日付の millisecondsSinceEpoch プロパティは、「Unix エポック」(1970 年 1 月 1 日 UTC)からのミリ秒数を返します。

dart
// 1/1/2000, UTC
var y2k = DateTime.utc(2000);
assert(y2k.millisecondsSinceEpoch == 946684800000);

// 1/1/1970, UTC
var unixEpoch = DateTime.utc(1970);
assert(unixEpoch.millisecondsSinceEpoch == 0);

Duration クラスを使用して、2 つの日付の差を計算し、日付を前後にシフトします。

dart
var y2k = DateTime.utc(2000);

// Add one year.
var y2001 = y2k.add(const Duration(days: 366));
assert(y2001.year == 2001);

// Subtract 30 days.
var december2000 = y2001.subtract(const Duration(days: 30));
assert(december2000.year == 2000);
assert(december2000.month == 12);

// Calculate the difference between two dates.
// Returns a Duration object.
var duration = y2001.difference(y2k);
assert(duration.inDays == 366); // y2k was a leap year.

メソッドの完全なリストについては、DateTime および Duration の API リファレンスを参照してください。

ユーティリティクラス

#

コアライブラリには、ソート、値のマッピング、イテレーションに役立つさまざまなユーティリティクラスが含まれています。

オブジェクトの比較

#

オブジェクトが通常ソートのために別のオブジェクトと比較できることを示すには、Comparable インターフェースを実装します。compareTo() メソッドは、小さい場合は < 0、同じ場合は 0、大きい場合は > 0 を返します。

dart
class Line implements Comparable<Line> {
  final int length;
  const Line(this.length);

  @override
  int compareTo(Line other) => length - other.length;
}

void main() {
  var short = const Line(1);
  var long = const Line(100);
  assert(short.compareTo(long) < 0);
}

マップキーの実装

#

Dart の各オブジェクトは自動的に整数ハッシュコードを提供するため、マップのキーとして使用できます。ただし、カスタムハッシュコードを生成するために hashCode getter をオーバーライドできます。そうする場合は、== 演算子もオーバーライドすることを検討してください。等しいオブジェクト (== 経由) は、同じハッシュコードを持つ必要があります。ハッシュコードは一意である必要はありませんが、分散が良好である必要があります。

dart
class Person {
  final String firstName, lastName;

  Person(this.firstName, this.lastName);

  // Override hashCode using the static hashing methods
  // provided by the `Object` class.
  @override
  int get hashCode => Object.hash(firstName, lastName);

  // You should generally implement operator `==` if you
  // override `hashCode`.
  @override
  bool operator ==(Object other) {
    return other is Person &&
        other.firstName == firstName &&
        other.lastName == lastName;
  }
}

void main() {
  var p1 = Person('Bob', 'Smith');
  var p2 = Person('Bob', 'Smith');
  var p3 = 'not a person';
  assert(p1.hashCode == p2.hashCode);
  assert(p1 == p2);
  assert(p1 != p3);
}

イテレーション

#

Iterable および Iterator クラスは、値のコレクションへの順次アクセスをサポートしています。これらのコレクションの使用練習をするには、Iterable コレクションチュートリアルに従ってください。

for-in ループで使用するための Iterator を提供できるクラスを作成する場合は、Iterable を拡張 (可能であれば) または実装します。Iterator を実装して、実際のイテレーション機能を定義します。

dart
class Process {
  // Represents a process...
}

class ProcessIterator implements Iterator<Process> {
  @override
  Process get current => ...
  @override
  bool moveNext() => ...
}

// A mythical class that lets you iterate through all
// processes. Extends a subclass of [Iterable].
class Processes extends IterableBase<Process> {
  @override
  final Iterator<Process> iterator = ProcessIterator();
}

void main() {
  // Iterable objects can be used with for-in.
  for (final process in Processes()) {
    // Do something with the process.
  }
}

例外

#

Dart コアライブラリは、多くの一般的な例外とエラーを定義しています。例外は、事前に計画してキャッチできる条件と見なされます。エラーは、予期しない、または計画していない条件です。

最も一般的なエラーのいくつかは次のとおりです。

NoSuchMethodError
受信オブジェクト(null である可能性もあります)がメソッドを実装していない場合にスローされます。
ArgumentError
予期しない引数に遭遇したメソッドによってスローされることがあります。

アプリケーション固有の例外をスローすることは、エラーが発生したことを示す一般的な方法です。Exception インターフェースを実装することで、カスタム例外を定義できます。

dart
class FooException implements Exception {
  final String? msg;

  const FooException([this.msg]);

  @override
  String toString() => msg ?? 'FooException';
}

詳細については、(言語ツアーの) 例外と、Exception API リファレンスを参照してください。

弱参照とファイナライザ

#

Dart は ガベージコレクション言語であり、参照されていない Dart オブジェクトはガベージコレクタによって破棄される可能性があります。このデフォルトの動作は、ネイティブリソースが関与するシナリオや、ターゲットオブジェクトを変更できない場合には望ましくない場合があります。

WeakReference は、ターゲットオブジェクトへの参照を格納しますが、ガベージコレクタによる収集方法には影響しません。もう 1 つのオプションは、Expando を使用してオブジェクトにプロパティを追加することです。

Finalizer は、オブジェクトが参照されなくなった後にコールバック関数を実行するために使用できます。ただし、このコールバックが実行されることは保証されません。

NativeFinalizer は、dart:ffi を使用したネイティブコードとの対話において、より強力な保証を提供します。そのコールバックは、オブジェクトが参照されなくなった後に少なくとも 1 回呼び出されます。また、データベース接続や開いているファイルなどのネイティブリソースを閉じるためにも使用できます。

オブジェクトが早期にガベージコレクトおよびファイナライズされないようにするには、クラスで Finalizable インターフェースを実装できます。ローカル変数が Finalizable の場合、宣言されているコードブロックが終了するまでガベージコレクトされません。