Позволяет ли dart пользователям писать реализацию для конкретной платформы?
Если нет - есть ли в планах это сделать?
Я знаю, что сам дротик имеет разные серверные части, которые могут иметь разную реализацию. Мне было любопытно, могут ли пользователи делать то же самое, например, иметь функцию, которая делегирует одному@patch
для среды выполнения js и для другого @patch
в случае dart vm.
2 ответа
Если вы создаете пакет, вы можете экспортировать разные реализации для разных платформ, см. Здесь: https://dart.dev/guides/libraries/create-library-packages
Способ создания кода, специфичного для платформы (или, скорее, кода, специфичного для библиотеки платформы), заключается в использовании условного импорта.
Синтаксис:
import "helper_default.dart"
if (dart.library.js) "helper_js.dart"
if (dart.library.io) "helper_io.dart";
Этот оператор импорта импортирует одну из трех библиотек. Еслиdart:js
библиотека доступна на платформе, для которой вы компилируете, вы импортируете helper_js.dart
. Если нет, иdart:io
доступен, то вы импортируете helper_io.dart
. Если этого тоже нет, вы импортируетеhelper_default.dart
.
Уловка состоит в том, чтобы один и тот же API библиотеки был реализован во всех трех библиотеках, но только на основе доступной библиотеки платформы. Вhelper_js.dart
библиотека может реализовать что-то, используя dart:js
а также helper_io.dart
может импортировать dart:io
. Библиотека по умолчанию, скорее всего, не сможет сделать ничего полезного, поэтому она может просто выброситьUnsupportedError
если вы попытаетесь его использовать.
Код в импортирующей библиотеке должен быть действителен для всех трех импортируемых файлов, поэтому у них должен быть "одинаковый" API. Это может включать объявление класса, но вы обычно определяете интерфейс этого класса в библиотеке, не зависящей от платформы, которую могут совместно использовать три реализации, чтобы гарантировать, что у них действительно один и тот же интерфейс.
Пример:
library mypkg.shared_types;
import "helper_default.dart"
if (dart.library.js) "helper_js.dart"
if (dart.library.io) "helper_io.dart"
as helper;
class SharedClass {
factory SharedClass(int something) = helper.SharedClassImpl;
int get value;
}
а также
library mypkg.helper_io;
import "dart:io";
import "shared_types.dart";
class SharedClassImpl implements SharedClass {
int _id;
SharedClassImpl(this._id);
int get value { // Something depending on dart:io.
var bytes = File("pathToSomething-$id").readAsBytesSync();
return bytes[0];
}
}