Bibliotheken Libraries

Jede Dart-Datei ist von Haus aus eine Bibliothek, auch ohne die library-Anweisung;

Datenschutzregel: Bezeichner, die mit Unterstrich _ beginnen, sind bibliotheksintern privat, nur innerhalb der gleichen Bibliothek sichtbar, über Dateien/Bibliotheken hinweg nicht zugänglich;

Es gibt keine Schlüsselwörter public/protected/private; Zugriffsrechte werden ausschließlich über den Unterstrich unterschieden;

Bibliotheken können als package verpackt und über pub verwaltet werden;

Vorteil: Ermöglicht Tree Shaking zum Entfernen ungenutzter Totcode.

import

Verwende das Schlüsselwort import, um andere Bibliotheken einzubinden.

import dient zum Einbinden von APIs aus anderen Bibliotheken

Drei URI-Typen:

  1. dart:xxx: Dart eingebaute Standardbibliotheken (dart:core, dart:async, dart:js_interop)
  2. package:xxx: Über pub verwaltete Drittbibliotheken
  3. Relative Dateipfade: Lokale selbst erstellte .dart-Dateien
// Eingebaute Standardbibliotheken
import 'dart:js_interop';
import 'dart:math';

// Drittpakete
import 'package:test/test.dart';

// Lokale Dateibibliothek
import './utils.dart';Code-Sprache: JavaScript (javascript)

Bibliotheksalias as

Wenn zwei Bibliotheken gleichnamige Klassen/Funktionen enthalten, nutze as Alias zur Trennung und Namensvermeidung.

Beispiel

In lib1.dart

class Element {}Code-Sprache: JavaScript (javascript)

lib2.dart enthält die gleiche Klasse

class Element {}Code-Sprache: JavaScript (javascript)

Hauptdatei main.dart

// Direkter Import, Standard-Namensraum
import 'lib1.dart';
// Alias lib2 zuweisen
import 'lib2.dart' as lib2;

void main() {
  Element e1 = Element(); // Element aus lib1
  lib2.Element e2 = lib2.Element(); // Element aus lib2
}Code-Sprache: JavaScript (javascript)

Um Namenskonflikte auszuschließen, weisen wir lib2.dart den Alias lib2 zu; beim Zugriff auf deren Klassen wird einfach der Alias-Präfix vorangestellt.

Selektiver Import show / hide

show: Nur angegebene Namen einbinden, alles andere ausblenden

// Nur foo importieren, andere Variablen/Klassen nicht nutzbar
import 'lib1.dart' show foo;

void main() {
  foo();
  // bar(); // Fehler, nicht über show importiert, nicht zugänglich
}Code-Sprache: JavaScript (javascript)

hide: Alles einbinden, nur angegebene Namen ausschließen

// Alles einbinden, nur foo blockieren
import 'lib2.dart' hide foo;

void main() {
  bar();
  // foo(); // Fehler, durch hide ausgeblendet
}Code-Sprache: JavaScript (javascript)

Verzögertes Laden deferred as

Nur auf der Web-Plattform wirksam

  • Verringert die anfängliche Ladegröße der Webseite;
  • Geeignet für selten genutzte Popups, optionale Seiten;
  • Lädt Code-Chunks bedingt dynamisch herunter.
  1. Import-Syntax: import Pfad deferred as Namensraum
  2. Aufruf von Namensraum.loadLibrary() gibt ein Future zurück, nutze await zum Warten auf den Ladeabschluss
  3. Mehrfacher Aufruf von loadLibrary() für dieselbe Bibliothek lädt nur einmal
  4. Einschränkung: Konstanten und Typen innerhalb verzögerter Bibliotheken können vor dem Laden nicht direkt verwendet werden

Vollständiges Beispiel

hello.dart (verzögert geladene Bibliothek)

void printGreeting() {
  print("Hello from deferred library wellcome to foxdevelop.com");
}
Code-Sprache: JavaScript (javascript)

main.dart

// Verzögerter Import mit Alias hello
import 'hello.dart' deferred as hello;

Future<void> greet() async {
  // Bibliothek dynamisch laden
  await hello.loadLibrary();
  // Erst nach abgeschlossenem Laden können interne Methoden aufgerufen werden
  hello.printGreeting();
}

void main() async {
  await greet();
}
Code-Sprache: JavaScript (javascript)

Ausgabe:

Hello from deferred library wellcome to foxdevelop.com
Code-Sprache: JavaScript (javascript)

Beide Dateien im gleichen Ordner ablegen

Wenn hello.dart in einem anderen Verzeichnis liegt, z. B. im übergeordneten lib-Ordner?

Pfadbeispiel: D:\dartdemo\firstdart\lib

main.dart befindet sich unter D:\dartdemo\firstdart\bin

firstdart/
├─ bin/
│  └─ firstdart.dart       // Programmeinstiegspunkt
└─ lib/
   └─ hello.dart      // Verzögert ladbare BibliothekCode-Sprache: JavaScript (javascript)

Dann lautet der Import wie folgt

// ../ steht für übergeordnetes Verzeichnis
import '../lib/hello.dart' deferred as hello;Code-Sprache: JavaScript (javascript)

Oberste Bibliotheksdeklaration library

Ganz oben in der Datei schreiben, dient zur Bibliotheksdokumentationskommentaren und bibliotheksweiten Annotationen (z. B. Einschränkung der Testplattform).

/// Nur für Browser bestimmte Testwerkzeug-Bibliothek
@TestOn('browser')
library;
Code-Sprache: JavaScript (javascript)

export

Exportieren (Kapselung einheitlicher öffentlicher APIs)

Häufig bei Werkzeugpaketen verwendet: bündelt mehrere Unterbibliotheken und stellt extern nur einen einzigen Import-Einstieg zur Verfügung.

Dateistruktur-Beispiel

src/math.dart

int add(int a, int b) => a + b;
int sub(int a, int b) => a - b;
Code-Sprache: PHP (php)

src/string.dart

String upper(String s) => s.toUpperCase();
Code-Sprache: JavaScript (javascript)

utils.dart (einheitlicher Export-Einstieg)

export 'src/math.dart';
export 'src/string.dart';
// Interne private Hilfswerkzeuge ausblenden
export 'src/internal.dart' hide helper;
Code-Sprache: JavaScript (javascript)

utils.dart kann nicht allein ausgeführt werden – es ist nur eine bündelnde Exportdatei ohne main()-Einstiegsfunktion, dart run lib/utils.dart funktioniert nicht;

Zweck von export

  • Bündelt APIs aus mehreren src-Unterdateien;
  • Nutzer braucht nur die Datei utils.dart einzubinden, um alle freigegebenen Methoden zu nutzen;
  • hide xxx blendet interne Hilfsfunktionen aus, kapselt Implementierungsdetails und steuert die nach außen sichtbaren APIs.

Verwendung in main.dart

import 'utils.dart';

void main() {
  print(add(1,2));
  print(upper("dart"));
}
Code-Sprache: JavaScript (javascript)

Hinweis

export/import sind nur Quellcode-Ein-/Ausgabe-Anweisungen; wenn Sie .dart-Quelldateien verteilen, können Dritte den gesamten Quellcode einsehen;

Um den Quellcode zu verbergen, müssen Sie keine .dart-Quelldateien veröffentlichen, sondern nur kompilierte binäre Snapshots verteilen.

Ein Snapshot ist eine binäre Datei nach Dart-Kompilierung; der vollständige lesbare Quellcode lässt sich nicht rückgewinnen, nur freigegebene APIs können aufgerufen werden.

Dieses Thema wird in anderen Kursen erläutert.

part

Aufteilung einer Bibliothek auf mehrere Dateien

Eine einzelne Bibliothek auf mehrere Dateien aufteilen, die unterstrichgestützte private Bezeichner gemeinsam nutzen. Es muss gepaart mit part 'xxx.dart' / part of 'Hauptdatei.dart' geschrieben werden

main_lib.dart (Hauptbibliotheksdatei)

library; // Deklariert, dass diese Datei eine Bibliothek ist
part 'logic.dart'; // logic.dart in die aktuelle Bibliothek einbinden, beide gehören zur gleichen Bibliothek

int _secret = 999; // Bibliotheksinterne private Variable
Code-Sprache: JavaScript (javascript)

logic.dart (Aufteilungsdatei)

part of 'main_lib.dart'; // Deklariert, dass diese Datei zu main_lib.dart gehört, keine eigenständige Bibliothek.

void printSecret() {
  // Kann auf _secret aus der Hauptdatei zugreifen, private Werte innerhalb einer Bibliothek werden gemeinsam genutzt
  print(_secret);
}
Code-Sprache: JavaScript (javascript)

Aufruf

import 'main_lib.dart'; // Nur die Hauptbibliothek importieren, NICHT die Aufteilungsdateien

void main() {
  printSecret(); // Ausgabe 999
}
Code-Sprache: JavaScript (javascript)

Bedingte Imports

Automatischer Wechsel der Implementierungsdateien je nach Ausführungsplattform

import 'platform_stub.dart'
    if (dart.library.io) 'platform_mobile.dart'
    if (dart.library.js_interop) 'platform_web.dart';
Code-Sprache: JavaScript (javascript)

Previous:

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert