توفر هذه الصفحة مقدمة موجزة عن لغة Dart من خلال عينات من ميزاتها الرئيسية.
لتعلم المزيد عن لغة دارت، قم بزيارة صفحات الموضوعات الفردية المتعمقة المدرجة تحت اللغة في القائمة الجانبية اليسرى.
للاطلاع على تفاصيل مكتبات Dart الأساسية، راجع وثائق المكتبة الأساسية . يمكنك أيضًا الاطلاع على ورقة الغش الخاصة بـ Dart ، للحصول على مقدمة أكثر تفاعلية.
مرحبا بالعالم
يتطلب كل تطبيق وظيفة المستوى الأعلى main()
، حيث يبدأ التنفيذ. الوظائف التي لا ترجع قيمة بشكل صريح لها void
نوع الإرجاع. لعرض النص على وحدة التحكم، يمكنك استخدام print()
وظيفة المستوى الأعلى:
سهم
void main() {
print('Hello, World!');
}
نسخة المحتوى
اقرأ المزيد حول الوظيفة في Dart، main()
بما في ذلك المعلمات الاختيارية لحجج سطر الأوامر.
المتغيرات
حتى في كود Dart الآمن للنوع ، يمكنك إعلان معظم المتغيرات دون تحديد نوعها صراحةً باستخدام var
. وبفضل استدلال النوع، يتم تحديد أنواع هذه المتغيرات من خلال قيمها الأولية:
سهم
var name = 'Voyager I';
var year = 1977;
var antennaDiameter = 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
'tags': ['saturn'],
'url': '//path/to/saturn.jpg'
};
نسخة المحتوى
اقرأ المزيد حول المتغيرات في Dart، بما في ذلك القيم الافتراضية، والكلمات الأساسية final
و const
، والأنواع الثابتة.
عبارات التحكم في التدفق
يدعم Dart عبارات تدفق التحكم المعتادة:
سهم
if (year >= 2001) {
print('21st century');
} else if (year >= 1901) {
print('20th century');
}
for (final object in flybyObjects) {
print(object);
}
for (int month = 1; month <= 12; month++) {
print(month);
}
while (year < 2016) {
year += 1;
}
نسخة المحتوى
اقرأ المزيد حول عبارات تدفق التحكم في Dart، بما في ذلك break
وcontinue
، switch
وcase
، و assert
.
الوظائف
نوصي بتحديد أنواع وسيطات كل دالة وقيمة الإرجاع:
سهم
int fibonacci(int n) {
if (n == 0 || n == 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
var result = fibonacci(20);
نسخة المحتوى
إن بناء الجملة المختصرة =>
( السهم ) مفيد للوظائف التي تحتوي على جملة واحدة. هذا البناء النحوي مفيد بشكل خاص عند تمرير وظائف مجهولة كحجج:
سهم
flybyObjects.where((name) => name.contains('turn')).forEach(print);
نسخة المحتوى
بالإضافة إلى إظهار دالة مجهولة (الحجّة إلى where()
)، يوضح هذا الكود أنه يمكنك استخدام دالة كحجة: print()
الدالة ذات المستوى الأعلى هي حجة إلى forEach()
.
اقرأ المزيد حول الوظائف في Dart، بما في ذلك المعلمات الاختيارية، وقيم المعلمات الافتراضية، والنطاق المعجمي.
تعليقات
تبدأ تعليقات دارت عادةً بـ //
.
سهم
// This is a normal, one-line comment.
/// This is a documentation comment, used to document libraries,
/// classes, and their members. Tools like IDEs and dartdoc treat
/// doc comments specially.
/* Comments like these are also supported. */
نسخة المحتوى
اقرأ المزيد حول التعليقات في Dart، بما في ذلك كيفية عمل أدوات التوثيق.
الواردات
للوصول إلى واجهات برمجة التطبيقات المحددة في مكتبات أخرى، استخدم import
.
سهم
// Importing core libraries
import 'dart:math';
// Importing libraries from external packages
import 'package:test/test.dart';
// Importing files
import 'path/to/my_other_file.dart';
نسخة المحتوى
اقرأ المزيد حول المكتبات والرؤية في Dart، بما في ذلك بادئات المكتبة، show
و hide
، والتحميل الكسول من خلال deferred
الكلمة الأساسية.
الفصول الدراسية
فيما يلي مثال لفئة بها ثلاث خصائص ومنشئان وطريقة. لا يمكن تعيين إحدى الخصائص بشكل مباشر، لذا يتم تعريفها باستخدام طريقة getter (بدلاً من متغير). تستخدم الطريقة استيفاء السلسلة لطباعة مكافئات السلسلة للمتغيرات داخل أحرف السلسلة.
سهم
class Spacecraft {
String name;
DateTime? launchDate;
// Read-only non-final property
int? get launchYear => launchDate?.year;
// Constructor, with syntactic sugar for assignment to members.
Spacecraft(this.name, this.launchDate) {
// Initialization code goes here.
}
// Named constructor that forwards to the default one.
Spacecraft.unlaunched(String name) : this(name, null);
// Method.
void describe() {
print('Spacecraft: $name');
// Type promotion doesn't work on getters.
var launchDate = this.launchDate;
if (launchDate != null) {
int years = DateTime.now().difference(launchDate).inDays ~/ 365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}
نسخة المحتوى
اقرأ المزيد حول السلاسل، بما في ذلك استيفاء السلاسل، والحرفيات، والتعبيرات، والطريقة toString()
.
يمكنك استخدام Spacecraft
الفصل على هذا النحو:
سهم
var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
voyager.describe();
var voyager3 = Spacecraft.unlaunched('Voyager III');
voyager3.describe();
نسخة المحتوى
اقرأ المزيد عن الفئات في Dart، بما في ذلك قوائم المبدئ، والمنشئين الاختياريين والموجهين، new
والمنشئين ، والمحصلين، والمحددين، وغير ذلك الكثير.const
factory
التعدادات
تعتبر العناصر المُعدّة طريقة لإحصاء مجموعة محددة مسبقًا من القيم أو الحالات بطريقة تضمن عدم وجود أي حالات أخرى من هذا النوع.
فيما يلي مثال بسيط enum
يحدد قائمة بسيطة لأنواع الكواكب المحددة مسبقًا:
سهم
enum PlanetType { terrestrial, gas, ice }
نسخة المحتوى
فيما يلي مثال لإعلان تعداد معزز لفئة تصف الكواكب، مع مجموعة محددة من الحالات الثابتة، وهي كواكب نظامنا الشمسي.
سهم
/// Enum that enumerates the different planets in our solar system
/// and some of their properties.
enum Planet {
mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
// ···
uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);
/// A constant generating constructor
const Planet(
{required this.planetType, required this.moons, required this.hasRings});
/// All instance variables are final
final PlanetType planetType;
final int moons;
final bool hasRings;
/// Enhanced enums support getters and other methods
bool get isGiant =>
planetType == PlanetType.gas || planetType == PlanetType.ice;
}
نسخة المحتوى
يمكنك استخدام Planet
التعداد على هذا النحو:
سهم
final yourPlanet = Planet.earth;
if (!yourPlanet.isGiant) {
print('Your planet is not a "giant planet".');
}
نسخة المحتوى
اقرأ المزيد حول التعدادات في Dart، بما في ذلك متطلبات التعدادات المحسّنة، والخصائص المقدمة تلقائيًا، والوصول إلى أسماء القيم المعدودة، ودعم عبارة التبديل، والمزيد.
الميراث
دارت لديه ميراث واحد.
سهم
class Orbiter extends Spacecraft {
double altitude;
Orbiter(super.name, DateTime super.launchDate, this.altitude);
}
نسخة المحتوى
اقرأ المزيد حول توسيع الفئات @override
والتعليقات التوضيحية الاختيارية والمزيد.
مزيجات
تعتبر Mixins طريقة لإعادة استخدام التعليمات البرمجية في تسلسلات هرمية متعددة للفئات. فيما يلي إعلان عن Mixin:
سهم
mixin Piloted {
int astronauts = 1;
void describeCrew() {
print('Number of astronauts: $astronauts');
}
}
نسخة المحتوى
لإضافة إمكانيات المزيج إلى فئة ما، ما عليك سوى توسيع الفئة باستخدام المزيج.
سهم
class PilotedCraft extends Spacecraft with Piloted {
// ···
}
نسخة المحتوى
PilotedCraft
الآن أصبح لديه astronauts
المجال وكذلك describeCrew()
الطريقة.
اقرأ المزيد عن الخلطات.
الواجهات والفئات المجردة
تحدد جميع الفئات واجهة ضمنية. وبالتالي، يمكنك تنفيذ أي فئة.
سهم
class MockSpaceship implements Spacecraft {
// ···
}
نسخة المحتوى
اقرأ المزيد عن الواجهات الضمنية ، أو عن interface
الكلمة الأساسية الصريحة .
يمكنك إنشاء فئة مجردة ليتم توسيعها (أو تنفيذها) بواسطة فئة ملموسة. يمكن أن تحتوي الفئات المجردة على طرق مجردة (بأجسام فارغة).
سهم
abstract class Describable {
void describe();
void describeWithEmphasis() {
print('=========');
describe();
print('=========');
}
}
نسخة المحتوى
Describable
تحتوي أي فئة ممتدة على describeWithEmphasis()
الطريقة التي تستدعي تنفيذ الموسع لـ describe()
.
اقرأ المزيد عن الفئات والأساليب المجردة.
غير متزامن
تجنب جحيم الاستدعاء العكسي وجعل الكود الخاص بك أكثر قابلية للقراءة عن طريق استخدام async
و await
.
سهم
const oneSecond = Duration(seconds: 1);
// ···
Future<void> printWithDelay(String message) async {
await Future.delayed(oneSecond);
print(message);
}
نسخة المحتوى
الطريقة المذكورة أعلاه تعادل:
سهم
Future<void> printWithDelay(String message) {
return Future.delayed(oneSecond).then((_) {
print(message);
});
}
نسخة المحتوى
كما يوضح المثال التالي، async
ويساعد await
ذلك في جعل الكود غير المتزامن سهل القراءة.
سهم
Future<void> createDescriptions(Iterable<String> objects) async {
for (final object in objects) {
try {
var file = File('$object.txt');
if (await file.exists()) {
var modified = await file.lastModified();
print(
'File for $object already exists. It was modified on $modified.');
continue;
}
await file.create();
await file.writeAsString('Start describing $object in this file.');
} on IOException catch (e) {
print('Cannot create description for $object: $e');
}
}
}
نسخة المحتوى
يمكنك أيضًا استخدام async*
، والذي يوفر لك طريقة جيدة وسهلة القراءة لبناء التدفقات.
سهم
Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
for (final object in objects) {
await Future.delayed(oneSecond);
yield '${craft.name} flies by $object';
}
}
نسخة المحتوى
اقرأ المزيد حول دعم عدم التزامن، بما في ذلك async
الوظائف، Future
و Stream
، والحلقة غير المتزامنة ( await for
).
الاستثناءات
لرفع استثناء، استخدم throw
:
سهم
if (astronauts == 0) {
throw StateError('No astronauts.');
}
نسخة المحتوى
للقبض على استثناء، استخدم try
عبارة مع on
أو catch
(أو كليهما):
سهم
Future<void> describeFlybyObjects(List<String> flybyObjects) async {
try {
for (final object in flybyObjects) {
var description = await File('$object.txt').readAsString();
print(description);
}
} on IOException catch (e) {
print('Could not describe object: $e');
} finally {
flybyObjects.clear();
}
}
نسخة المحتوى
لاحظ أن الكود أعلاه غير متزامن؛ try
فهو يعمل لكل من الكود المتزامن والكود الموجود في async
الدالة.
اقرأ المزيد حول الاستثناءات، بما في ذلك تتبعات المكدس، rethrow
والفرق بين Error
و Exception
.
مفاهيم مهمة
مع استمرارك في التعلم عن لغة دارت، ضع هذه الحقائق والمفاهيم في الاعتبار:
- كل ما يمكنك وضعه في متغير هو كائن ، وكل كائن هو مثيل لفئة . حتى الأرقام والوظائف و
null
هي كائنات. باستثناءnull
(إذا قمت بتمكين أمان الصوت )، فإن جميع الكائنات ترث منObject
الفئة.نوع الدمجملاحظة الإصدارتم تقديم ميزة الأمان ضد العدم في Dart 2.12. يتطلب استخدام ميزة الأمان ضد العدم إصدار لغة لا يقل عن 2.12. - على الرغم من أن Dart من النوع القوي، فإن التعليقات التوضيحية للنوع اختيارية لأن Dart يمكنه استنتاج الأنواع. في
var number = 101
،number
يُستنتج أنه من النوعint
. - إذا قمت بتمكين أمان القيمة الفارغة ، فلن تتمكن المتغيرات من الاحتواء
null
إلا إذا قلت إنها تستطيع ذلك. يمكنك جعل متغير قابلاً للقيمة الفارغة عن طريق وضع علامة استفهام (?
) في نهاية نوعه. على سبيل المثال،int?
قد يكون متغير من النوع عددًا صحيحًا، أو قد يكونnull
. إذا كنت تعلم أن تعبيرًا ما لا يتم تقييمه أبدًاnull
ولكن Dart لا يوافق على ذلك، فيمكنك إضافة!
التأكيد على أنه ليس فارغًا (وإلقاء استثناء إذا كان كذلك). مثال:int x = nullableButNotNullInt!
- عندما تريد أن تقول صراحةً أن أي نوع مسموح به، استخدم النوع
Object?
(إذا قمت بتمكين أمان العدم)،Object
أو -إذا كان يجب عليك تأجيل فحص النوع حتى وقت التشغيل- النوع الخاصdynamic
. - يدعم Dart الأنواع العامة، مثل
List<int>
(قائمة من الأعداد الصحيحة) أوList<Object>
(قائمة من الكائنات من أي نوع). - يدعم Dart الوظائف ذات المستوى الأعلى (مثل
main()
)، بالإضافة إلى الوظائف المرتبطة بفئة أو كائن ( الطرق الثابتة والمثيلة ، على التوالي). يمكنك أيضًا إنشاء وظائف داخل وظائف ( وظائف متداخلة أو محلية ). - على نحو مماثل، يدعم Dart المتغيرات ذات المستوى الأعلى ، بالإضافة إلى المتغيرات المرتبطة بفئة أو كائن (المتغيرات الثابتة والمتغيرات المثيلة). تُعرف متغيرات المثيل أحيانًا بالحقول أو الخصائص .
- على عكس Java، لا تحتوي Dart على الكلمات الأساسية
public
وprotected
و وprivate
. إذا بدأ المعرف بعلامة سفلية (_
)، فهو خاص بمكتبته. للحصول على التفاصيل، راجع المكتبات والواردات . - يمكن أن تبدأ المعرفات بحرف أو شرطة سفلية (
_
)، متبوعة بأي مجموعة من تلك الأحرف بالإضافة إلى الأرقام. - تحتوي لغة Dart على تعبيرات (تحتوي على قيم وقت التشغيل) وعبارات (لا تحتوي على قيم). على سبيل المثال، تحتوي عبارة الشرط
condition ? expr1 : expr2
على قيمةexpr1
أوexpr2
. قارن ذلك بعبارة if-else ، والتي لا تحتوي على أي قيمة. غالبًا ما تحتوي العبارة على تعبير واحد أو أكثر، ولكن لا يمكن أن تحتوي عبارة بشكل مباشر على عبارة. - يمكن لأدوات Dart الإبلاغ عن نوعين من المشكلات: التحذيرات والأخطاء . التحذيرات هي مجرد مؤشرات على أن الكود الخاص بك قد لا يعمل، لكنها لا تمنع برنامجك من التنفيذ. يمكن أن تكون الأخطاء إما وقت التجميع أو وقت التشغيل. يمنع خطأ وقت التجميع الكود من التنفيذ على الإطلاق؛ ويؤدي خطأ وقت التشغيل إلى إثارة استثناء أثناء تنفيذ الكود