Dart: أساسيات Dart — بنية البرنامج والتعليقات والكود
آخر تحديث: 2026-08-26
بناء الجملة هو هيكل الكود — عادات بناء الجملة الموحدة تحدد قابلية قراءة الكود وصيانته.
1. ما ستتعلمه
- دالة
main()الرئيسية ونموذج تنفيذ البرنامج - الفواصل المنقوطة، الأقواس المعقوفة، واتفاقيات المسافة البادئة (قواعد dart format)
- ثلاثة أنواع من التعليقات: تعليق السطر / تعليق الكتلة / تعليق التوثيق (
///) - نظرة عامة على الكلمات المفتاحية والكلمات المحجوزة
2. قصة مطور حقيقي
(1) نقطة الألم: لماذا يبدو كود الزميل مثل السحر؟
دخل تشارلي (متدرب جديد) إلى فريق تطوير Dart ووجد أن كود زميله "لا يمكن فهمه على الإطلاق". نفس 10 أسطر من الكود يمكن أن يكون لها 3 أنماط: لا توجد تعليقات، تعليقات // TODO، أو /// تعليقات توثيق. سأل الرئيس: "ما الفرق؟" أجاب: "تعمل الآن، لكن بعد 3 أشهر لن تفهم حتى أنت نفسك."
(2) حل Dart
// كود سيء — يعمل، لكن لا يمكن صيانته
int a=1;
if(a>0){print(a);}
/// الكود الجيد — يعمل ويمكن صيانته
const int initialCount = 1; // الثوابت المسماة أوضح من الأرقام السحرية
void main() {
if (initialCount > 0) { // المسافة البادئة الموحدة + الأقواس الحصرية
print(initialCount);
}
}
(3) النتيجة: 3 أنماط → معيار واحد، قابلية الصيانة +5 مرات
| المؤشر | قبل التوحيد | بعد التوحيد |
|---|---|---|
| تنوع أنماط الكود في الفريق | 3+ أنماط | 1 معيار |
| الوقت لفهم كود الزملاء | 30 دقيقة/يوم | 5 دقائق/يوم |
| الأخطاء الناجمة عن تنسيق غير متسق | 5/شهر | <1/شهر |
| سرعة مراجعات PR | 2 ساعة/PR | 30 دقيقة/PR |
قبل: 3 أنماط، 5 أخطاء/شهر، 2 ساعة لمراجعة PR
بعد: 1 معيار، <1 خطأ/شهر، 30 دقيقة لمراجعة PR
ROI: +5 مرات قابلية صيانة
3. دالة main(): نقطة دخول البرنامج
(1) لماذا main()؟
كل لغة برمجة لها اصطلاح لإعلان نقطة الدخول، Dart ليست استثناءً:
| اللغة | نقطة الدخول |
|---|---|
| C/C++ | int main(int argc, char** argv) |
| Java | public static void main(String[] args) |
| Python | لا حاجة للإعلان (الملف نفسه نقطة الدخول) |
| JavaScript | لا حاجة للإعلان (الملف نفسه نقطة الدخول) |
| Go | func main() |
| Dart | void main() |
(2) توقيعات main الأربعة
// أبسط شكل — لا معاملات، لا قيمة إرجاع
void main() {
print('Hello, Dart!');
}
// مع معاملات سطر الأوامر
void main(List<String> arguments) {
print('معاملات: ${arguments.length}');
}
// دالة غير متزامنة (للعمليات async)
Future<void> main() async {
await fetchData();
}
// دالة غير متزامنة مع معاملات
Future<void> main(List<String> arguments) async {
await processArgs(arguments);
}
▶ مثال: استكشاف دالة main
// bin/main.dart
import 'dart:io';
void main(List<String> arguments) {
// 1. اطبع التحية
print('مرحبًا، Dart!');
// 2. اطبع معاملات سطر الأوامر
print('المعاملات: $arguments');
// 3. اطبع إصدار Dart واسم النظام الأساسي
print('إصدار Dart: ${Platform.version}');
print('نظام التشغيل: ${Platform.operatingSystem}');
}
$ dart run bin/main.dart arg1 --flag value
مرحبًا، Dart!
المعاملات: [arg1, --flag, value]
إصدار Dart: 3.4.0 (stable) (Wed May 29 05:02:00 2024 +0000) on "macos_x64"
نظام التشغيل: macos
> **الإخراج:** main() هو نقطة دخول البرنامج، Platform.* يوفر معلومات بيئة وقت التشغيل.
(3) مثال: عملية CLI كاملة
// bin/greeter.dart
import 'dart:io';
void main(List<String> arguments) {
// التحقق من المعاملات
if (arguments.isEmpty) {
print('الاستخدام: dart run bin/greeter.dart <الاسم>');
exit(1); // رمز الخروج 1 يعني خطأ
}
final name = arguments[0];
print('مرحبًا، $name!');
// رمز الخروج 0 يعني نجاح
exit(0);
}
$ dart run bin/greeter.dart
الاستخدام: dart run bin/greeter.dart <الاسم>
$ echo $?
1
$ dart run bin/greeter.dart Bob
مرحبًا، Bob!
$ echo $?
0
> **الإخراج:** رموز الخروج 0/1 هي اصطلاح، البرامج النصية يمكنها استخدام exit(code) لإبلاغ نظام التشغيل بحالة النجاح/الفشل.
4. الفواصل المنقوطة، الأقواس المعقوفة، والمسافة البادئة
(1) هل الفواصل المنقوطة مطلوبة؟
Dart 3 يجعل الفواصل المنقوطة اختيارية (ستضيفها تلقائيًا في وقت الترجمة)، لكن الاصطلاح الموصى به هو كتابتها بوضوح:
// ✅ موصى به — الفواصل المنقوطة الصريحة تجعل نوايا الكود واضحة
void main() {
print('Hello');
print('World');
}
// ⚠️ قانوني لكن غير موصى به — لا فواصل منقوطة
void main() {
print('Hello')
print('World')
}
السبب الموصى به:
dart formatسيضيفها تلقائيًا (لا داعي للقلق بشأن الاتساق)- عند نسخ كود إلى REPL أو لقطات شاشة، لا تنساه
- أكثر صراحة في نية الكود
(2) الأقواس المعقوفة: 4 أنماط، 1 موصى به
// ✅ موصى به (K&R / Allman-blended) — فتح القوس في نهاية السطر
void main() {
if (true) {
print('Hello');
}
}
// ⚠️ قانوني لكن غير شائع — فتح القوس في سطر منفصل (Allman)
void main()
{
if (true)
{
print('Hello');
}
}
// ❌ كود سيء — لا توجد أقواس (Kotlin/Python style) — Dart لا يدعمه
// void main()
// print('Hello') // ❌ خطأ في وقت الترجمة
// }
(3) المسافة البادئة: 2 مسافات (وليس 4)
// ✅ موصى به — 2 مسافات للمسافة البادئة
void main() {
if (true) {
for (var i = 0; i < 3; i++) {
if (i > 0) {
print(i);
}
}
}
}
// ❌ خطأ — 4 مسافات (ليس اصطلاح Dart)
void main() {
if (true) {
for (var i = 0; i < 3; i++) {
if (i > 0) {
print(i);
}
}
}
}
▶ مثال: dart format لتنسيق تلقائيًا
# 1. أنشئ ملف كود سيء التنسيق
$ cat bad_style.dart
void main(){print('Hello');if(true){print('World');}}
# 2. تنسيق
$ dart format bad_style.dart
Formatted 1 file in 0.02s.
# 3. عرض النتيجة
$ cat bad_style.dart
void main() {
print('Hello');
if (true) {
print('World');
}
}
> **الإخراج:** dart format سيضع الفراغات، الأسطر الجديدة، الأقواس، المسافة البادئة بشكل صحيح — لا حاجة للتفاوض مع المراجعين حول الأسلوب.
(4) خط طول السطر: 80 حرف
// ✅ جيد — ضمن 80 حرف
String getName() {
return 'Bob';
}
// ⚠️ طويل جدًا — أكثر من 80 حرفًا، يجب الالتفاف
String getFormattedUserInformation({required String name, required int age}) {
return 'User $name is $age years old';
}
// ✅ بعد الالتفاف
String getFormattedUserInformation({
required String name,
required int age,
}) {
return 'User $name is $age years old';
}
| البُعد | التوصية |
|---|---|
| طول السطر | 80 حرف (افتراضي) |
| حجم المسافة البادئة | 2 مسافات |
| نوع المسافة البادئة | مسافات (وليس Tab) |
| الفراغات حول المشغلين | a + b (وليس a+b) |
| الفاصلة المنقوطة | إلزامية (مكتوبة صراحة) |
(5) تكوين dart format المخصص
أنشئ .dart_tool/dartfmt.cfg في جذر المشروع:
line-length=100
أو في analysis_options.yaml:
formatter:
line_length: 100
5. ثلاثة أنواع من التعليقات
(1) تعليق السطر: //
// هذا تعليق سطر واحد
void main() {
print('Hello'); // تعليق بعد الكود (سطر لاحق)
// print('World'); // تم التعليق على هذا السطر
}
الاستخدامات: شرح سطر واحد، أو إضافة سياق مؤقت.
(2) تعليق الكتلة: /* ... */
/*
* تعليق كتلة متعدد الأسطر
* الصف الأول
* الصف الثاني
*
* الصف الفارغ يفصل الفقرات
*/
void main() {
/*
تعليق كتلة غير مرتب
قد يكون أي شيء
*/
print('Hello');
}
الاستخدامات: تعليقات مؤقتة طويلة، تعطيل أقسام من الكود أثناء التصحيح.
(3) تعليق التوثيق: /// (أو /** */)
/// حساب مجموع عددين صحيحين.
///
/// [a] العدد الأول
/// [b] العدد الثاني
///
/// يُرجع مجموع [a] و [b].
int add(int a, int b) {
return a + b;
}
الاستخدامات: توليد وثائق API تلقائيًا (مثل dart doc).
▶ مثال: مقارنة ثلاثة أنواع من التعليقات
// 1. تعليق السطر — شرح بسيط
int x = 1; // متغير العداد
// 2. تعليق الكتلة — تعطيل مؤقت
/*
void debugPrint() {
print('Debug mode enabled');
}
*/
// 3. تعليق التوثيق — إنشاء API doc
/// إضافة [a] و [b] وإرجاع النتيجة.
///
/// مثال:
/// ```dart
/// final sum = add(1, 2);
/// print(sum); // 3
/// ```
int add(int a, int b) => a + b;
void main() {
print(add(1, 2)); // 3
}
# عرض وثائق API لـ add()
$ dart doc .
Documenting add...
# عرض مساعدة سطر الأوامر (إذا تم تكوين pubspec.yaml)
$ dart run bin/greeter.dart --help
> **الإخراج:** dart doc يولد وثائق HTML من /// التعليقات، يمكن للمستخدمين رؤية الاستخدام والمعاملات وقيم الإرجاع.
(4) أفضل ممارسات التعليقات
// ❌ سيء — يصف ما يفعله الكود (الكود نفسه يقول ذلك)
i++; // زيادة i بمقدار 1
// ✅ جيد — يشرح لماذا
i++; // تخطي العنصر الأول (header row)
// ❌ سيء — تعليق قديم
// TODO: إصلاح الخوارزمية
// (الكود التالي لا علاقة له بالخوارزمية)
// ✅ جيد — تعليق دقيق
// TODO: استبدال بـ O(n log n) sort عندما تتجاوز البيانات 10K
// التاريخ: 2024-12-15
// المالك: @bob
| القاعدة | المثال |
|---|---|
| اشرح لماذا، وليس ماذا | // لزيادة العداد (سيء) → // لتتبع عدد المحاولات (جيد) |
| حافظ على تحديثها | التعليقات القديمة أكاذيب |
| استخدم TODO مع المؤلف | // TODO(@bob): ... |
| أضف السياق | التاريخ، السبب، القرار |
6. الكلمات المفتاحية والكلمات المحجوزة
(1) الكلمات المفتاحية الـ 50 في Dart 3
// الكلمات المفتاحية Dart 3 — مرتبة أبجديًا
const abstract
as assert async await
break
case catch class const continue
default defer do dynamic
else enum export extends
extension external
factory false final finally for
Function
get
hide
if implements import in interface is
late library
mixin
new null
on operator
part required return
rethrow
sealed set show static super switch
sync
this throw true try
typedef
var
void
when while with
yield
(2) الكلمات المحجوزة (غير مستخدمة حاليًا)
// محجوزة للاستخدام المستقبلي
abstract
as
static
// لا يمكن استخدامها كأسماء متغيرات
(3) قواعد تسمية المتغيرات
// ✅ تسمية جيدة
int userCount = 10; // camelCase + اسم وصفي
String firstName = 'Bob';
bool isActive = true;
final double pi = 3.14159;
const int maxRetries = 3;
// ❌ تسمية سيئة
int a = 10; // اسم غير وصفي
String s = 'Bob'; // اسم مفرد محير
bool flag = true; // ما هو العلم؟
final double PI = 3.14159; // ثابت — يجب أن يكون const
const int MAX = 3; // snake_case غير اصطلاحية لـ Dart
▶ مثال: نظرة عامة على الكلمات المفتاحية الشائعة
// إعلان متغير
var name = 'Bob'; // استنتاج النوع
String name = 'Bob'; // نوع صريح
final name = 'Bob'; // غير قابل للتعيين (وقت التشغيل)
const name = 'Bob'; // ثابت وقت الترجمة
late String name; // تهيئة كسولة
// التحكم في التدفق
if (condition) { ... } else { ... }
for (var i = 0; i < 10; i++) { ... }
while (condition) { ... }
switch (value) { case 1: ...; default: ...; }
// دالة
void doSomething() { ... }
int add(int a, int b) => a + b;
Future<void> fetchData() async { ... }
// الفئة
class User {
String name;
User(this.name);
}
// استيراد
import 'dart:io';
import 'package:http/http.dart';
> **الإخراج:** ~50 كلمة مفتاحية، تغطي الإعلانات، التحكم في التدفق، الفئات، الاستيراد، التزامن. Dart أبسط من C++ (~90 كلمة مفتاحية) أو Java (~50 كلمة مفتاحية).
(4) التحقق من تسمية المتغيرات
# استخدم dart analyze للتحقق من تسمية المتغيرات
$ dart analyze
warning • Variable name 'user_count' should be lowerCamelCase at lib/calculator.dart:5:7
7. مقارنة بأسلوب C/Java/JavaScript
| البُعد | Dart | C | Java | JavaScript |
|---|---|---|---|---|
| حجم المسافة البادئة | 2 مسافات | 4 مسافات | 4 مسافات | 2 مسافات |
| نمط تسمية المتغير | camelCase | snake_case | camelCase | camelCase |
| نمط تسمية الفئة | PascalCase | PascalCase | PascalCase | PascalCase |
| فاصل الجملة | إلزامي | إلزامي | إلزامي | اختياري (ASI) |
| قوس مفتوح | نهاية السطر | نهاية السطر | نهاية السطر | نهاية السطر |
| صيغة التشكيل | dart format | clang-format | google-java-format | prettier |
// Dart 3 — اصطلاح سلسلة camelCase + 2 مسافة بادئة + فواصل منقوطة إلزامية
class UserRepository {
final String firstName;
final String lastName;
final int userId;
UserRepository({
required this.firstName,
required this.lastName,
required this.userId,
});
String getFullName() => '$firstName $lastName';
}
(1) أداة dart fix للإصلاح التلقائي
# الإصلاحات التلقائية الأكثر شيوعًا
$ dart fix --apply
37 fixes made in 12 files
# إصلاحات محددة فقط
$ dart fix --apply --code=unused_import
3 fixes made in 3 files
# المعاينة فقط (لا تعديل)
$ dart fix --dry-run
| نوع الإصلاح | الوصف |
|---|---|
unused_import |
إزالة الواردات غير المستخدمة |
prefer_const_constructors |
تحويل المُنشئات إلى const |
unnecessary_this |
إزالة this. غير الضروري |
prefer_single_quotes |
تحويل علامات الاقتباس المزدوجة إلى مفردة |
sort_child_properties_last |
فرز خصائص مُنشئ الفئة الفرعية |
8. ملخص نقاط المعرفة الأساسية لهذا الدرس
| # | المفهوم | المستوى | الأهمية |
|---|---|---|---|
| 1 | main() هي نقطة الدخول، تدعم 4 توقيعات |
مبتدئ | ⭐⭐⭐⭐⭐ |
| 2 | الفواصل المنقوطة اختيارية لكن يوصى بكتابتها | مبتدئ | ⭐⭐ |
| 3 | الأقواس على نفس السطر + 2 مسافة بادئة = اصطلاح | مبتدئ | ⭐⭐⭐⭐⭐ |
| 4 | ثلاثة أنواع من التعليقات: // / /* */ / /// |
مبتدئ | ⭐⭐⭐⭐ |
| 5 | 50 كلمة مفتاحية في Dart 3، استكمال من ~80 في Dart 2 | مبتدئ | ⭐⭐⭐ |
| 6 | dart format و dart fix لتنسيق وإصلاح تلقائي |
مبتدئ | ⭐⭐⭐⭐⭐ |
❓ أسئلة شائعة
default محجوز، لكن defaultValue مسموح. هذا اصطلاح معتمد في JavaScript/TypeScript/Dart.dart format لإضافة الفواصل المنقوطة بسلاسة. النمط الموصى به لا يزال كتابتها صراحةً.dart doc ستحللها كوثائق API وتولد HTML. اختلاف دقيق: الثلاثي يجب أن يكون على السطر السابق للرمز، والكتلي يمكن أن يكون في أي مكان.dart format في مشروع يستخدم إصدار Dart قديم؟dart format متوافق مع الإصدارات السابقة. ستعمل في مشاريع Dart 2.12+ (التي تدعم null safety). بالنسبة للمشاريع الأقدم، قد لا تفهم بعض بناء الجملة الجديد.dart fix آمن للاستخدام في كود الإنتاج؟dart fix يطبق فقط الإصلاحات التي أوصى بها فريق Dart، مع اختبار الانحدار. ولكن يجب عليك تشغيل git status أولاً، واستخدام --dry-run للمعاينة، وإجراء مراجعة الكود. لا تستبدل كود مكتوبًا عمدًا بدون تحقق.📖 ملخص
- نقطة الدخول:
void main()أوFuture<void> main() async، 4 توقيعات - اصطلاح التنسيق: 2 مسافة بادئة + قوس في نهاية السطر + فواصل منقوطة + 80 حرف
- ثلاثة تعليقات:
//للسطر //* */للكتلة ////للتوثيق - أدوات تلقائية:
dart format(تنسيق) +dart fix(إصلاح) +dart analyze(فحص) - الكلمات المفتاحية: 50 كلمة مفتاحية في Dart 3، أبسط من C++ (90) ومن نفس مستوى Java (50)
- مقارنة الأساليب: Dart يتبع camelCase + 2 مسافة بادئة، مثل JS/TS
📝 تمارين
- أساسي (الصعوبة ⭐): أنشئ مشروع
syntax_practice، واكتب ثلاثة أشكال من main (متزامن/غير متزامن/مع معاملات) في ملفات مختلفة (bin/sync.dart/bin/async.dart/bin/args.dart)، واستخدمdart formatلتنسيقها، وتحقق من أنها كلها تعمل عبرdart run. تلميح: استخدمFuture.delayedفي الإصدار غير المتزامن لإظهار الفرق. - متوسط (الصعوبة ⭐⭐): أنشئ مشروع
comment_quality، واكتب دالةcalculateTax، واستخدم ثلاثة أنواع من التعليقات لشرح نفس المنطق: ① تعليق سطر لشرح السطر الأكثر أهمية ② تعليق كتلة لشرح المنطق العام للدالة ③ تعليق توثيق///للدالة بأكملها (بما في ذلك المعلمات وقيم الإرجاع والأمثلة). ثم شغّلdart docلتوليد الوثائق وتحقق من ظهور التعليقات في الإخراج. تلميح: استخدم[paramName]في///لإنشاء روابط المعلمات. - تحدٍّ (الصعوبة ⭐⭐⭐): أنشئ مشروع
code_style_compare، واكتب نفس دالة الآلة الحاسبة (مثلevaluate(String expression)) بثلاثة أساليب: ① 4 مسافات بادئة + لا فواصل منقوطة (سيئ) ② 2 مسافات بادئة + فواصل منقوطة + 80 حرف لكل سطر (Dart) ③ نفس Dart + ولكن استخدمdart fixلتطبيق جميع الإصلاحات. قارن عدد الأسطر، تعقيد القراءة، وعدد التحذيرات/الأخطاء منdart analyze. تلميح: استخدمdart format bad.dartوdart format good.dartلمقارنة النتائج.
← السابق: تركيب بيئة التطوير والأدوات | التالي: المتغيرات وأنواع البيانات →