1. مقدمة
لغة Dart هي لغة البرمجة في Flutter، وهي مجموعة أدوات واجهة مستخدم من Google في تصميم تطبيقات رائعة متوافقة مع الأجهزة الجوّالة والويب وأجهزة كمبيوتر سطح المكتب من قاعدة رموز واحدة.
يعرض لك هذا الدرس التطبيقي حول Dart مع التركيز على الميزات التي قد لا يتوقعها مطوّرو البرامج باستخدام جافا. يمكنك كتابة دوال السهم خلال دقيقة واحدة، والنصوص البرمجية خلال 5 دقائق، والتطبيقات في 10 دقائق.
ما ستتعرَّف عليه
- كيفية إنشاء أدوات وضع
- طرق مختلفة لتحديد المعلمات
- كيفية إنشاء عمليات الضبط وإعدادها
- كيفية معالجة السهم
- كيفية إنشاء مصانع
- آلية عمل البرمجة الوظيفية في Dart
- مفاهيم السهم الأساسية الأخرى
الأشياء التي تحتاج إليها
لإكمال هذا الدرس التطبيقي حول الترميز، ما عليك سوى استخدام متصفّح.
ستتمكّن من كتابة جميع الأمثلة وعرضها في DartPad، وهي أداة تفاعلية مستندة إلى المتصفِّح تتيح لك استخدام ميزات لغة السهم ومكتبات أساسية. يمكنك استخدام IDE بدلاً من ذلك، مثل WebStorm أو IntelliJ باستخدام المكوّن الإضافي Dart أو Visual Studio Code مع إضافة Dart Code.
ما الذي تريد تعلّمه من هذا الدرس التطبيقي حول الترميز؟
2. إنشاء صف بسيط للعبة السهم
ستبدأ;؛بإنشاء فئة الأسهم البسيطة التي تحتوي على الوظائف نفسها كصف Bicycle
من البرنامج التعليمي لجافا. تحتوي الفئة Bicycle
على بعض متغيّرات المثيلات الخاصة من خلال أدوات الاستدعاء والضبط. تعمل الطريقة main()
على إنشاء نسخة افتراضية من Bicycle
وطباعتها على وحدة التحكم.
تشغيل DartPad
يتيح هذا الدرس التطبيقي حول الترميز الحصول على مثيل DartPad جديد لكل مجموعة من التمارين. يفتح الرابط أدناه مثيلاً حديثًا يحتوي على مثال افتراضي "&Hello;quot; يمكنك مواصلة استخدام نفسها لـ DartPad طوال الدرس التطبيقي، ولكن في حال النقر على إعادة ضبط، ستعيدك DartPad إلى المثال التلقائي، وستفقد عملك.
تحديد فئة الدراجة
فوق الدالة
main()
، أضِف فئة Bicycle
تتضمّن ثلاثة متغيرات افتراضية. يجب أيضًا إزالة المحتوى من main()
، كما هو موضّح في مقتطف الرمز التالي:
class Bicycle {
int cadence;
int speed;
int gear;
}
void main() {
}
الملاحظات
- في هذا المثال، ينتج عن أداة تحليل السهم خطأ يخبرك بضرورة إعداد المتغيرات لأنها غير قابلة للإفراغ. سيتم إصلاح ذلك في القسم التالي.
- وتُسمى الطريقة الأساسية لـ " السهام"
main()
. في حال كنت بحاجة إلى الوصول إلى وسيطات سطر الأوامر، يمكنك إضافتها:main(List<String> args)
. - وصلت طريقة
main()
إلى المستوى الأعلى. في السهم، يمكنك تحديد الرمز خارج الصفوف. يمكن أن تكون المتغيّرات والدوال والمتغيّرات وأدوات التجهيز متوفرة خارج الصفوف الدراسية. - يذكر مثال Java الأصلي متغيرات المثيل الخاص باستخدام العلامة
private
، والتي لا تستخدمها Dart. ستتعرّف على المزيد من المعلومات عن الخصوصية في وقت لاحق، في &إضافة متغيّر للقراءة فقط. - لم يتم الإعلان عن
main()
أوBicycle
باعتبارهpublic
، لأنّ جميع المعرّفات علنية بشكل تلقائي. لا تحتوي السهم السهمي على كلمات رئيسية لـpublic
أوprivate
أوprotected
. - تستخدم سهم الأسهم مسافة بادئة مؤلفة من حرفين بدلاً من أربعة أحرف. لا داعي للقلق بشأن اصطلاحات المسافة البيضاء في الأسهم. بحسب اصطلاحات رمز السهم ( لعبة السهم النشِط) تقول، "القواعد الرسمية للتعامل مع المسافة البيضاء في سهم
تعريف أداة إنشاء الدراجات
يمكنك إضافة طريقة وضع التصميم التالية إلى الفئة
Bicycle
:
Bicycle(this.cadence, this.speed, this.gear);
الملاحظات
- هذه البنية بدون نص، وهي صالحة في السهم.
- إذا نسيت الفاصلة المنقوطة (
;
) في نهاية طريقة إنشاء بدون نص، يعرض DartPad الخطأ التالي: "؛يجب تقديم نص الدالة. - إنّ استخدام
this
في قائمة معلّمات للمُنشئين هو اختصار مفيد لتخصيص القيم لمتغيرات المثيل. - يتساوى الرمز أعلاه في ما يلي، والذي يستخدم قائمة المُعدِّل:
Bicycle(int cadence, int speed, int gear)
: this.cadence = cadence,
this.speed = speed,
this.gear = gear;
تنسيق الرمز
يمكنك إعادة تنسيق رمز Dart في أي وقت من خلال النقر على تنسيق أعلى واجهة مستخدم DartPad. وتتم إعادة التنسيق بشكلٍ مفيد عند لصق الرمز في DartPad وإيقاف الضبط.
انقر على تنسيق.
إنشاء مثيل مثيل دراجة وطباعته
أضِف الرمز التالي إلى الدالة
main()
:
void main() {
var bike = new Bicycle(2, 0, 1);
print(bike);
}
إزالة الكلمة الرئيسية
new
الاختيارية:
var bike = Bicycle(2, 0, 1);
الملاحظة
- أصبحت الكلمة الرئيسية على
new
اختيارية في Dart 2. - إذا كنت تعرف أن قيمة المتغيّر لن تتغير، يمكنك استخدام
final
بدلاً منvar
. - تقبل الدالة
print()
أي كائن (وليس سلاسل فقط). وتحوِّله إلىString
باستخدام طريقةtoString()
للعنصر.
تنفيذ المثال
نفِّذ المثال بالنقر على تشغيل في أعلى نافذة DartPad. في حال عدم تفعيل التشغيل، راجع قسم المشاكل لاحقًا في هذه الصفحة.
ومن المفترض أن يظهر لك الناتج التالي:
Instance of 'Bicycle'
الملاحظة
- يجب ألا تظهر أي أخطاء أو تحذيرات تشير إلى أن نوع الاستنتاج يعمل، وأنّ أداة التحليل تستنتج أنّ العبارة التي تبدأ بـ
var bike =
تحدّد مثيل دراجة.
تحسين الناتج
على الرغم من أنّ ناتج "دراجة" هو مثال صحيح، إلا أنه ليس مفيدًا للغاية. تتضمّن جميع صفوف Dart طريقة toString()
يمكنك إلغاؤها لتقديم نتائج أكثر فائدة.
إضافة طريقة
toString()
التالية في أي مكان في الفئة Bicycle
:
@override
String toString() => 'Bicycle: $speed mph';
الملاحظات
- يخبر التعليق التوضيحي
@override
أداة التحليل بأنك تلغي عضوًا عن قصد. وتعرض أداة التحليل خطأً في حال عدم تنفيذ عملية الإلغاء بشكلٍ سليم. - تدعم سهم السهم علامات الاقتباس المفردة أو المزدوجة عند تحديد السلاسل.
- استخدِم استقراء السلسلة لوضع قيمة تعبير داخل سلسلة حرفية:
${expression}
. إذا كان التعبير معرّفًا، يمكنك تخطّي الأقواس:$variableName
. - يجب اختصار الدوال المكوّنة من سطر واحد أو طرقها باستخدام ترميز السهم الدهني (
=>
).
تنفيذ المثال
انقر على تشغيل.
ومن المفترض أن يظهر لك الناتج التالي:
Bicycle: 0 mph
هل تواجه أي مشاكل؟تحقّق من الرمز.
إضافة متغيّر للقراءة فقط
يحدّد مثال Java الأصلي speed
على أنّه متغيّر للقراءة فقط، ويعلنه على أنه خاص ولا يقدّم سوى القيمة إرجاع. بعد ذلك، ستقدّم الوظيفة نفسها في السهم.
فتح
bicycle.dart
في DartPad (أو مواصلة استخدام نسختك)
لوضع علامة على معرّف Dart باعتباره خاصًا لمكتبته، ابدأ اسمه بشرطة سفلية (_
). يمكنك تحويل speed
إلى القراءة فقط من خلال تغيير اسمه وإضافة إرجاع.
جعل السرعة متغيّرًا خاصًا للقراءة فقط
في طريقة إنشاء
Bicycle
، يجب إزالة المعلمة speed
:
Bicycle(this.cadence, this.gear);
في
main()
، أزِل المعلّمة الثانية (speed
) من الاستدعاء إلى دالة إنشاء Bicycle
:
var bike = Bicycle(2, 1);
غيِّر مواضع التكرار المتبقية من
speed
إلى _speed
. (مكانان)
ضبط
_speed
على 0:
int _speed = 0;
أضِف القيمة التالية إلى فئة
Bicycle
:
int get speed => _speed;
الملاحظات
- يجب إعداد كل متغيّر (حتى لو كان رقمًا) أو إعداد قيمة خالية منه عن طريق إضافة
?
إلى تعريف النوع. - يفرض مجمِّع محتوى Dart خصوصية المكتبة لأي معرّف مسبوق بشرطة سفلية. تعني خصوصية المكتبة بشكل عام أن المعرّف مرئي فقط داخل الملف (وليس فقط الفئة) الذي تم تحديد المعرّف فيه.
- توفِّر لغة Dart تلقائيًا أدوات الرصد وال ضمنية لجميع متغيّرات المثيل العام. ولن تحتاج إلى تحديد مُحدِّدات أو أدوات ضبط خاصة بك ما لم تكن تريد فرض متغيرات للقراءة فقط أو تعديلات للقراءة فقط أو حساب قيمة أو التحقُّق منها أو تحديث قيمة في مكان آخر.
- قدّمت عيّنة Java الأصلية أدوات ضبط ودعامات لكل من
cadence
وgear
. لا يحتاج نموذج السهم الإلكتروني إلى مُحدِّدات وأدوات إعداد تسمح بذلك، وبالتالي فهو يستخدم متغيّرات المثيلات فقط. - يمكنك البدء بالحقل البسيط، مثل
bike.cadence
، ثم إعادة تفعيله لاحقًا لاستخدام أجهزة التلقيم والضبط. تظل واجهة برمجة التطبيقات كما هي. بعبارة أخرى، لا يُعدّ الانتقال من حقل إلى إرجاع القيمة المحدّدة تغييرًا مكسورًا في السهم.
إنهاء سرعة التنفيذ كمتغيّر في القراءة فقط
أضِف الطرق التالية إلى الصف
Bicycle
:
void applyBrake(int decrement) {
_speed -= decrement;
}
void speedUp(int increment) {
_speed += increment;
}
يبدو مثال السهم المعدّل النهائي مشابهًا لشكل Java الأصلي، ولكنه أكثر ضغطًا في 23 سطرًا بدلاً من 40 سطرًا:
class Bicycle {
int cadence;
int _speed = 0;
int get speed => _speed;
int gear;
Bicycle(this.cadence, this.gear);
void applyBrake(int decrement) {
_speed -= decrement;
}
void speedUp(int increment) {
_speed += increment;
}
@override
String toString() => 'Bicycle: $_speed mph';
}
void main() {
var bike = Bicycle(2, 1);
print(bike);
}
هل تواجه أي مشاكل؟تحقّق من الرمز.
3- استخدام المعلمات الاختيارية (بدلاً من التحميل الزائد)
يحدد التمرين التالي Rectangle
صف، وهو مثال آخر على البرنامج التعليمي لجافا.
يعرض رمز Java مواد التشغيل التي تُفرط في التحميل، وهي ممارسة شائعة في Java تتّبع أسماء طرق الإنشاء نفسها، ولكنها تختلف في عدد المعلمات أو نوعها. لا تدعم لغة البرمجة سهم من خلال إنشاء التصاميم الزائدة وتتعامل مع هذا الموقف بشكل مختلف، كما سترى في هذا القسم.
افتَح مثال المستطيل في DartPad.
إضافة منشئ مستطيل
أضِف دالة إنشاء واحدة فارغة وتستبدل طرق الإنشاء الأربعة في نموذج جافا:
Rectangle({this.origin = const Point(0, 0), this.width = 0, this.height = 0});
تستخدم طريقة وضع التصميم هذه معلّمات اسمية اختيارية.
الملاحظات
- يستخدِم كل من
this.origin
وthis.width
وthis.height
الحيلة المخصّصة لتعيين المتغيّرات الافتراضية في بيان المُنشئ. this.origin
وthis.width
وthis.height
هي معلّمات اختيارية. المعلّمات المُسَمّاة محاطة بأقواس معقوفة ({}
).- تحدِّد البنية
this.origin = const Point(0, 0)
القيمة التلقائية لـPoint(0,0)
للمتغيّرorigin
. يجب أن يكون الإعداد التلقائي المحدّد ثابت وقت التجميع. تقدّم طريقة وضع التصميم هذه القيم التلقائية لجميع المتغيرات الثلاثة الافتراضية.
تحسين الناتج
أضِف الدالة
toString()
التالية إلى الفئة Rectangle
:
@override
String toString() =>
'Origin: (${origin.x}, ${origin.y}), width: $width, height: $height';
استخدام عامل البناء
استبدل
main()
بالرمز التالي للتحقق من أنه يمكنك إنشاء مثيل Rectangle
باستخدام المعلمات التي تحتاج إليها فقط:
main() {
print(Rectangle(origin: const Point(10, 20), width: 100, height: 200));
print(Rectangle(origin: const Point(10, 10)));
print(Rectangle(width: 200));
print(Rectangle());
}
الملاحظة
- تعدّ"أداة إنشاء السهم"لـ
Rectangle
سطرًا واحدًا من الرموز، مقارنةً بـ 16 سطرًا من الرموز للتصميمات المكافئة في إصدار جافا.
تنفيذ المثال
ومن المفترض أن يظهر لك الناتج التالي:
Origin: (10, 20), width: 100, height: 200
Origin: (10, 10), width: 0, height: 0
Origin: (0, 0), width: 200, height: 0
Origin: (0, 0), width: 0, height: 0
هل تواجه أي مشاكل؟تحقّق من الرمز.
4. إنشاء مصنع
وهناك العديد من المزايا التي تُعدّ نمطًا شائع الاستخدام للتصميم في لغة Java، العديد من الفوائد التي تنتج عن إنشاء الكائنات مباشرةً، مثل إخفاء تفاصيل المحاكاة الافتراضية، وتوفير إمكانية عرض نوع فرعي من نوع المنتج الذي تم إرجاعه على الإعدادات الأصلية، وعرض كائن حالي بدلاً من عرض كائن جديد.
توضح هذه الخطوة طريقتين لتنفيذ مصنع إنشاء الأشكال:
- الخيار الأول: إنشاء دالة من المستوى الأعلى.
- الخيار 2: إنشاء ملف شخصي للمصنع.
بالنسبة إلى هذا التمرين، ستستخدم مثال الأشكال، الذي ينشئ مثيلات للمساحة ويطبع المساحة التي تم احتسابها:
import 'dart:math';
abstract class Shape {
num get area;
}
class Circle implements Shape {
final num radius;
Circle(this.radius);
num get area => pi * pow(radius, 2);
}
class Square implements Shape {
final num side;
Square(this.side);
num get area => pow(side, 2);
}
main() {
final circle = Circle(2);
final square = Square(2);
print(circle.area);
print(square.area);
}
في منطقة وحدة التحكم، يجب أن تظهر المناطق المحسوبة في دائرة ومربّع:
12.566370614359172
4
الملاحظات
- توفّر لعبة سهم السهم صفوفًا تجريدية.
- ويمكنك تحديد العديد من الصفوف في ملف واحد.
dart:math
هي إحدى مكتبات Dart's الأساسية. وتشمل المكتبات الأساسية الأخرىdart:core
وdart:async
وdart:convert
وdart:collection
.- حسب الاتفاقية، ثوابت مكتبة السهم هي
lowerCamelCase
(على سبيل المثال،pi
بدلاً منPI)
). إذا كنت فضوليًا بشأن المنطق، فراجِع إرشادات النمط PREFER باستخدام أدنىCamelCase بالنسبة إلى الأسماء الثابتة. - يعرض الرمز التالي دالتَين تحسبان قيمة:
num get area => pi * pow(radius, 2); // Circle num get area => pow(side, 2); // Square
الخيار الأول: إنشاء دالة من المستوى الأعلى
تنفيذ المصنّف كدالة المستوى الأعلى عن طريق إضافة الدالة التالية على أعلى مستوى (خارج أي فئة):
Shape shapeFactory(String type) {
if (type == 'circle') return Circle(2);
if (type == 'square') return Square(2);
throw 'Can\'t create $type.';
}
استدعاء دالة المصنع من خلال استبدال أول سطرين في طريقة
main()
:
final circle = shapeFactory('circle');
final square = shapeFactory('square');
تنفيذ المثال
يجب أن تكون المخرجات كما كانت من قبل.
الملاحظات
- إذا تم استدعاء الدالة بأي سلسلة بخلاف
'circle'
أو'square'
، ستعرض استثناءً. - تحدّد حزمة تطوير البرامج (Dart SDK) الفئات للعديد من الاستثناءات الشائعة، أو يمكنك تنفيذ الفئة
Exception
لإنشاء استثناءات أكثر تحديدًا أو (كما في هذا المثال) يمكنك طرح سلسلة تصف المشكلة التي واجهتها. - وعند حدوث استثناء، تُبلغ ميزة DartPad عن
Uncaught
. لعرض معلومات أكثر فائدة، يُرجى وضع الرمز في بيانtry-catch
وطباعة الاستثناء. وكممارسة اختيارية، اطّلِع على مثال DartPad هذا. - لاستخدام علامة اقتباس فردية داخل سلسلة، يمكنك تخطي علامة الاقتباس المضمّنة باستخدام الشرطة المائلة (
'Can\'t create $type.'
) أو تحديد السلسلة التي تتضمّن علامات اقتباس مزدوجة ("Can't create $type."
).
هل تواجه أي مشاكل؟تحقّق من الرمز.
الخيار 2: إنشاء شركة مصنِّعة
استخدام الكلمة الرئيسية لـ Dart'factory
لإنشاء إنشاء مصنع.
إضافة دالة إنشاء للمصنع إلى فئة
Shape
المجرّدة:
abstract class Shape {
factory Shape(String type) {
if (type == 'circle') return Circle(2);
if (type == 'square') return Square(2);
throw 'Can\'t create $type.';
}
num get area;
}
استبدل أول سطرين من
main()
بالرمز التالي لإنشاء مثيلات الأشكال:
final circle = Shape('circle');
final square = Shape('square');
احذف دالة
shapeFactory()
التي أضفتها سابقًا.
الملاحظة
- يكون الرمز في طريقة وضع المصنع هو الرمز نفسه الظاهر في الدالة
shapeFactory()
.
هل تواجه أي مشاكل؟تحقّق من الرمز.
5. تنفيذ واجهة
لا تتضمن لغة السهم لغة كلمة رئيسية باللغة interface
لأن كل صف يحدد واجهة.
فتح مثال الأشكال في DartPad (أو مواصلة استخدام نسختك).
أضِف فئة
CircleMock
تنفِّذ واجهة Circle
:
class CircleMock implements Circle {}
من المفترض أن تظهر لك رسالة خطأ م&فقودة في عمليات التنفيذ الخرسانية المفقودة نظرًا لأن
CircleMock
لا يرث تنفيذ Circle
—بل يستخدم الواجهة فقط. يمكنك إصلاح هذا الخطأ عن طريق تحديد المتغيّرَين للمثيلَين area
وradius
:
class CircleMock implements Circle {
num area = 0;
num radius = 0;
}
الملاحظة
- على الرغم من أن فئة
CircleMock
لا تحدد أي سلوكيات، فهي صالحة لـ السهم. لا ينتج عن المحلل أي أخطاء. - ينفذ المتغيّر
area
للصيغةCircleMock
قيمة إرجاعarea
لدالةCircle
.
هل تواجه أي مشاكل؟تحقّق من الرمز.
6- استخدام ميزة السهم لبرمجة الوظائف
في البرمجة الوظيفية، يمكنك تنفيذ الإجراءات التالية:
- تعمل الدوال كوسيطات.
- إسناد دالة إلى متغيّر.
- يمكنك تحليل الدالة التي تأخذ وسيطات متعددة في تسلسل من الدوال التي تأخذ كل منها وسيطة واحدة (تُسمى أيضًا الكاري).
- يمكنك إنشاء دالة بلا اسم يمكن استخدامها كقيمة ثابتة (تُسمى أيضًا تعبير lambda، وتمت إضافة تعبيرات lambda إلى Java في إصدار JDK 8).
تتوفر ميزة السهم هذه. في Dart، حتى الدوال هي كائنات وتحتوي على النوع، Function
. وهذا يعني أنّه يمكن تخصيص الدوال للمتغيرات أو تمريرها كوسيطات لدوال أخرى. ويمكنك أيضًا استدعاء مثيل لفئة Dart كما لو كانت دالة، كما في هذا المثال.
يستخدم المثال التالي رمزًا إلزاميًا (ليس أسلوبًا وظيفيًا):
String scream(int length) => "A${'a' * length}h!";
main() {
final values = [1, 2, 3, 5, 10, 50];
for (var length in values) {
print(scream(length));
}
}
يجب أن يظهر الناتج على النحو التالي:
Aah!
Aaah!
Aaaah!
Aaaaaah!
Aaaaaaaaaaah!
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah!
الملاحظة
- عند استخدام إقحام السلسلة، يتم تقييم السلسلة
${'a' * length}
على &الحرف'a'
المكررlength
مرة."
تحويل الرمز اللازم إلى تنسيق وظيفي
أزِل حلقة
for() {...}
الضرورية في main()
واستبدِلها بسطر واحد من الرمز يستخدِم سلسلة الطريقة:
values.map(scream).forEach(print);
تنفيذ المثال
يطبّق المنهج العملي الصراخ نفسه على النحو الوارد في المثال الأساسي.
هل تواجه أي مشاكل؟تحقّق من الرمز.
استخدام المزيد من الميزات القابلة للتكرار
تتوافق صفوف List
وIterable
الأساسية مع fold()
وwhere()
وjoin()
وskip()
وغيرها. وتتضمّن اللعبة أيضًا ميزة السهم المضمّنة في "خرائط Google" ومجموعاتها.
استبدل السطر
values.map()
فيmain()
بما يلي:
values.skip(1).take(3).map(scream).forEach(print);
تنفيذ المثال
يجب أن يظهر الناتج على النحو التالي:
Aaah!
Aaaah!
Aaaaaah!
الملاحظات
skip(1)
يتخطّى القيمة الأولى، 1، في قائمةvalues
الحرفية.take(3)
تحصل على القيم الثلاث التالية — 2 و3 و5 - في القائمةvalues
الحرفية.- ويتم تخطي القيم المتبقية.
هل تواجه أي مشاكل؟تحقّق من الرمز.
7- تهانينا.
من خلال إكمال هذا الدرس التطبيقي حول الترميز، تعرّفت على بعض الاختلافات بين Java وDart. يسهل تعلّم لغة Dart، بالإضافة إلى مكتباتها الأساسية ومجموعةها الغنية من الحزم المتاحة تزيد من إنتاجيتك. يتم توسعة لعبة السهم بشكل جيد مع التطبيقات الكبيرة. يستخدم مئات من مهندسي Google شركة Dart لكتابة تطبيقات ذات أهمية كبرى تحقق قدرًا كبيرًا من أرباح Google.
الخطوات اللاحقة
درس تطبيقي حول الترميز لمدة 20 دقيقة ليس كافيًا ليعرض لك كل الاختلافات بين Java وDart. على سبيل المثال، لم يتناول هذا الدرس التطبيقي الترميز:
- غير المتزامنة/الانتظار، مما يتيح لك كتابة رمز غير متزامن كما لو كان متزامنًا. اطّلِع على مثال DartPad هذا، الذي يوضِّح رسمًا لحساب العمليات العشرية الخمسة الأولى لـ Č.
- قصص تتدفق من خلالها إلى الوراء حيث كل شيء هو بنّاء
- عوامل التشغيل الواعية
إذا كنت تريد الاطّلاع على تقنيات Dart، يمكنك تجربة مختبرات Flutter.
مزيد من المعلومات
يمكنك الاطّلاع على المزيد من المعلومات حول Dart من خلال المقالات والمراجع والمواقع الإلكترونية التالية.
المقالات
- أسباب استخدام Flutter
- الإعلان عن Dart 2: تم تحسينه لتطوير البرامج من جهة العميل
- لماذا انتقلت من Java إلى Dart؟
المراجع
المواقع الإلكترونية