اگر آپ ایک ماہ سے زیادہ عرصے سے فلٹر کوڈ لکھ رہے ہیں، تو آپ نے شاید درج ذیل سطر کو سینکڑوں بار لکھا ہوگا:
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
آپ دیکھ سکتے ہیں کہ ہر پیرامیٹر کو کس قسم کی ضرورت ہے۔ IDE جانتا ہے۔ ڈارٹ کمپائلر جانتا ہے۔ تاہم، جب بھی آپ ٹائپ کریں گے، آپ ڈاٹ سے پہلے مکمل قسم کا نام دہرائیں گے۔ MainAxisAlignment.center. CrossAxisAlignment.start. MainAxisSize.min. آپ تین لفظوں میں ایک بات کہہ سکتے ہیں جب اردگرد کے حالات پہلے ہی قسم کو بالکل واضح کر چکے ہوں۔
یہ الگ تھلگ رگڑ نہیں ہے۔ یہ ڈارٹ اور فلٹر میں ہر جگہ ظاہر ہوتا ہے۔ تم لکھو Colors.blue درج ذیل پیرامیٹرز کے لیے: Color. تم لکھو BorderRadius.circular(8) درج ذیل پیرامیٹرز کے لیے: BorderRadius. تم لکھو Duration.zero درج ذیل فیلڈ میں درج کیا گیا: Duration. تم لکھو TextAlign.center درج ذیل پیرامیٹرز کے لیے: TextAlign.
تمام معاملات میں قسم پہلے سے ہی پیرامیٹر کی تعریف میں ہے اور اسے دوبارہ ہجے کرنے کی ضرورت ہے کیونکہ زبان کو اس کی ضرورت ہے۔
ڈارٹ 3.10، جو 12 نومبر 2025 کو فلٹر 3.38 کے ساتھ ریلیز ہوا، اس مسئلے کو حل کرنے کے لیے ڈاٹ مخففات متعارف کرایا۔ ڈاٹ شارٹننگ آپ کو صرف ڈاٹ اور ممبر کا نام لکھنے کی اجازت دیتا ہے جب کمپائلر پہلے سے ہی سیاق و سباق سے قسم کو جانتا ہو۔ مثال کے طور پر، .center اس کے بجائے MainAxisAlignment.center. .circular(8) اس کے بجائے BorderRadius.circular(8). .zero اس کے بجائے Duration.zero. ہجے والے قسم کے نام اب اختیاری ہیں۔ کیونکہ مرتب کرنے والا اس کا اندازہ لگا سکتا ہے اور کرے گا۔
یہ ایک کاسمیٹک خصوصیت نہیں ہے۔ یہ ان جگہوں پر بصری شور میں کافی حد تک کمی ہے جہاں فلٹر ڈویلپرز سب سے زیادہ کوڈ لکھتے ہیں: ویجیٹ ٹریز، سوئچ اسٹیٹمنٹس، شماری اسائنمنٹس، اور کنسٹرکٹر کالز۔
جب آپ اسے پہلی بار اپنے اصل کوڈ بیس میں چالو کرتے ہیں، Column اور Row پیرامیٹرز نمایاں طور پر صاف ہیں۔ آپ کے سوئچ بیانات نثر سے ملتے جلتے ہیں۔ آپ کا کوڈ کہتا ہے کہ اس کا کیا مطلب ہے بغیر سابقہ وزن کے۔
یہ کتابچہ تقدیر کی تکنیکوں کے لیے ایک مکمل رہنما ہے۔ یہ نہ صرف نحو کا احاطہ کرتا ہے بلکہ اس کے پیچھے ذہنی ماڈل بھی شامل ہے۔ ہم اس بات کا احاطہ کریں گے کہ کمپائلر کچھ جگہوں پر اقسام کا کیوں اندازہ لگا سکتا ہے اور دوسروں پر نہیں، قیاس کے اصول کیسے کام کرتے ہیں، جہاں شارٹ ہینڈ واقعی طاقتور ہے، اور جہاں یہ خاموشی سے کوڈ کو پڑھنا مشکل بنا دیتا ہے۔
بہت سے فلٹر ڈویلپرز نے ریلیز نوٹ میں ذکر کردہ خصوصیات کو دیکھا لیکن انہیں پوری طرح سے سمجھ نہیں آیا کہ وہ کتنی گہری ہیں۔ یہ کتابچہ مکمل تصویر فراہم کرتا ہے۔
آخر کار، آپ پورے اعتماد کے ساتھ ڈاٹ شارٹ کٹس کو شماروں، جامد طریقوں، جامد فیلڈز، کنسٹرکٹرز، سوئچ اسٹیٹمنٹس، مساوات کی جانچ پڑتال، کالعدم اقسام، اور غیر مطابقت پذیر واپسی اظہارات میں استعمال کرنے کے قابل ہو جائیں گے۔ آپ یہ بھی جان لیں گے کہ کن حالات میں فیچر کام نہیں کر رہا ہے اور کیوں۔
انڈیکس
شرطیں
یہ گائیڈ فرض کرتا ہے کہ آپ کے پاس پہلے سے ہی کچھ بنیادی معلومات اور مہارتیں ہیں۔ آپ کو ان میں سے کسی ایک شعبے میں ماہر ہونے کی ضرورت نہیں ہے، لیکن آپ کو ہر ایک میں عملی بنیاد رکھنی چاہیے۔
ڈارٹس کی بنیادی باتیں: آپ کو کلاسز، شماریات، جامد ممبران، کنسٹرکٹرز اور نامزد کنسٹرکٹرز کو سمجھنے کی ضرورت ہے۔ اگر آپ فرق جانتے ہیں۔ ClassName.member اور instance.memberاور آپ سمجھتے ہیں کیا static اس کا مطلب ہے کہ میدان یا طریقہ تیار ہے۔
فلٹر ویجیٹ کی بنیادی باتیں: آپ کو اسے آرام سے استعمال کرنے کی ضرورت ہے۔ Column, Row, Containerاور اسی طرح کے ویجٹ۔ گائیڈ فلٹر ویجیٹ پیرامیٹرز کو ایک اہم حوصلہ افزا مثال کے طور پر استعمال کرتا ہے، کیونکہ یہ وہ جگہ ہے جہاں ڈاٹ شارٹ ہینڈ کا سب سے زیادہ نمایاں اثر ہوتا ہے۔
ڈارٹ کی قسم کا نظام: یہ سمجھنا ضروری ہے کہ ڈارٹ میں ہر متغیر، پیرامیٹر، اور فیلڈ کی ایک قسم ہوتی ہے، اور اس قسم کا یا تو واضح طور پر اعلان کیا جاتا ہے یا مرتب کرنے والے کے ذریعے اندازہ لگایا جاتا ہے۔ یہ سمجھنا کہ مرتب کرنے والا کوڈ کے عمل سے پہلے اقسام کو جانتا ہے یہ سمجھنے کے لیے بنیادی ہے کہ سیاق و سباق کا اندازہ کیسے کام کرتا ہے۔
Dart SDK 3.10 اور Flutter 3.38 یا اس سے زیادہ: ڈاٹ شارٹ ہینڈ ایک لینگویج ورژن محدود فیچر ہے۔ آپ کو اپنے پروجیکٹ میں ڈارٹ 3.10 کو منتخب کرنا ہوگا۔ SDK رکاوٹوں کو اپ ڈیٹ کریں۔ pubspec.yaml:
environment:
sdk: ^3.10.0
یہ رکاوٹ ڈارٹ SDK کو بتاتی ہے کہ پیکیج ڈارٹ 3.10 یا اس سے زیادہ کے لیے لکھا گیا ہے اور پروجیکٹ میں موجود تمام ڈارٹ فائلوں کے لیے ڈاٹ شارٹننگ سنٹیکس کو کھول دیتا ہے۔
اس تبدیلی کے بغیر، اگر آپ استعمال کرتے ہیں: .center یا .zero مجھے یہ کہتے ہوئے ایک تالیف کی خرابی ملتی ہے کہ ڈاٹ شارٹ کٹ کے لیے زبان کا ورژن 3.10 یا اس سے زیادہ درکار ہے۔ اگر آپ فلٹر استعمال کر رہے ہیں تو چلائیں: flutter upgrade آپ کو صرف SDK رکاوٹوں کو اپ ڈیٹ کرنا ہے۔
تجرباتی ڈارٹ پیڈ: آپ https://dartpad.dev پر اس گائیڈ میں مثالوں کو انٹرایکٹو جانچ سکتے ہیں۔ DartPad Dart 3.10 کو سپورٹ کرتا ہے اور یہ جانچنے کا تیز ترین طریقہ ہے کہ آیا کوئی مخصوص مخفف کسی مخصوص صورت حال میں کام کرتا ہے۔
ڈاٹ شارٹ ہینڈ کیا ہے؟
براہ راست تشبیہ کے ساتھ شروع کریں۔
تصور کریں کہ آپ ایک فارم پُر کر رہے ہیں جس میں ایک فیلڈ ہے جسے "ملک” کہتے ہیں۔ میدان کے بائیں جانب پہلے ہی ‘ملک:’ لکھا ہوا ہے۔ "نائیجیریا” لکھیں۔ باکس میں ‘ملک: نائجیریا’ نہ لکھیں۔ اس کی وجہ یہ ہے کہ لیبل پہلے ہی اس زمرے کی نشاندہی کرتا ہے جس کی قیمت ہے۔
یہ ڈیوی ایشن شارٹ ہینڈ کا کام ہے۔ جب ڈارٹ پہلے ہی ارد گرد کے سیاق و سباق سے جانتا ہے کہ قدر ایک قسم کی ہونی چاہیے۔ MainAxisAlignmentبس لکھو .center اس کے بجائے MainAxisAlignment.center. قسم کا لیبل پہلے سے موجود ہے۔ شارٹ کٹ آپ کو صرف اقدار لکھنے کی اجازت دیتے ہیں۔
تکنیکی تعریف
ڈاٹ شارٹ ہینڈ ڈاٹ ہے (.) کو سیاق و سباق کی قسم تک جامد ممبر کی رسائی تک حل کیا جاتا ہے۔ جب مرتب کرنے والا ارد گرد کے سیاق و سباق سے جانتا ہے کہ اظہار ایک قسم کا ہونا چاہیے۔ Tتحریر .member مندرجہ ذیل کے طور پر علاج کیا جاتا ہے: T.member. تحریر .new(args) مندرجہ ذیل کے طور پر علاج کیا جاتا ہے: T.new(args) (بے نام کنسٹرکٹر) لکھیں۔ .namedConstructor(args) مندرجہ ذیل کے طور پر علاج کیا جاتا ہے: T.namedConstructor(args).
کلیدی جملہ "واضح سیاق و سباق کی قسم” ہے۔ سیاق و سباق کی قسم کمپائلر کے ذریعہ متوقع قسم ہے جہاں آپ اظہار لکھتے ہیں۔ یہ اس سے آتا ہے:
-
متغیر کی اعلان شدہ قسم تفویض کی جا رہی ہے۔
-
اعلان کردہ فنکشن پیرامیٹر کی قسم جس کی قدر پاس کی گئی ہے۔
-
جب کوئی قدر واپس کی جاتی ہے تو اعلان کردہ فنکشن کی واپسی کی قسم۔
-
بائیں طرف جامد قسم
==یا!=موازنہ کریں (خصوصی قواعد) -
انیشیلائزر میں اعلان کردہ فیلڈ کی اقسام
اگر مرتب کرنے والے اظہار کی جانچ کرنے سے پہلے ان ذرائع میں سے کسی ایک سے قسم کا تعین کیا جا سکتا ہے، تو ڈاٹ شارٹ ہینڈ وہاں درست ہے۔ اگر سیاق و سباق کی قسم دستیاب نہیں ہے تو ڈاٹ شارٹ ہینڈ ایک مرتب وقت کی غلطی ہے۔
مسئلہ: تقدیر سے پہلے کی زندگی
دہرانے والا پیٹرن
اپنے فلٹر پروجیکٹ کو کھولیں اور اہم اسکرینوں کے لیے ویجیٹ ٹری پر ایک نظر ڈالیں۔ آپ کو کچھ اس طرح نظر آئے گا:
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'Hello',
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
),
Icon(Icons.chevron_right),
],
),
SizedBox(height: 16),
Container(
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.white,
),
child: Text('World'),
),
],
)
اس کوڈ میں، آپ گنتی کی قسم کے نام کی تکرار کی تعداد گنتے ہیں۔ MainAxisAlignment یہ دو بار ظاہر ہوتا ہے۔ CrossAxisAlignment یہ دو بار ظاہر ہوتا ہے۔ لفظ MainAxisAlignment, CrossAxisAlignment, TextAlign, TextOverflow, Alignment, BorderRadius, Colors یہ سب لکھا ہوا ہے۔
اور ان میں سے ہر ایک کے لیے پیرامیٹر میں قسم کا پہلے ہی اعلان کر دیا گیا ہے۔ mainAxisAlignment خلل MainAxisAlignment, crossAxisAlignment خلل CrossAxisAlignmentوغیرہ۔ پیرامیٹر کا نام ہی قسم کی معلومات پر مشتمل ہے۔ تاہم، ڈاٹ سے پہلے مکمل قسم کا نام درکار تھا۔
یہ صرف بصری شور نہیں تھا۔ یہ علمی شور تھا۔ ویجیٹ ٹری کو پڑھتے وقت، پیرامیٹر کے ناموں اور اصل قدروں کے درمیان قسم کے نام آنکھوں کو سست کر دیتے ہیں۔ اگر تمام متعلقہ معلومات "mainAxisAlignment colon center” میں ہیں تو آپ کا دماغ "mainAxisAlignment colon MainAxisAlignment ڈاٹ سینٹر” پڑھے گا۔
بیان کا مسئلہ سوئچ کریں۔
اینوم پر مبنی سوئچ بیانات میں بھی یہی مسئلہ تھا۔
switch (status) {
case NetworkStatus.connecting:
return const CircularProgressIndicator();
case NetworkStatus.connected:
return const Icon(Icons.wifi);
case NetworkStatus.disconnected:
return const Icon(Icons.wifi_off);
case NetworkStatus.error:
return const Icon(Icons.error);
}
متغیر status یہ پہلے ہی درج ذیل کے طور پر درج کیا جا چکا ہے: NetworkStatus. ہر case تو یہ کام کرتا ہے: NetworkStatus قدر تحریر NetworkStatus.connecting, NetworkStatus.connected, NetworkStatus.disconnectedاور NetworkStatus.error تمام صورتوں میں یہ خالص تکرار ہے۔ قسم کا نام سوئچ ہدف پر پہلے سے جانا جاتا ہے، لہذا اس میں کوئی معلومات شامل نہیں ہوتی ہے۔
یہ پیٹرن Dart 3.10 سے پہلے ناگزیر تھا۔ یہ صرف وہی قیمت ہے جو آپ ایک مستحکم سیاق و سباق میں زبان کے لفظی پن کے لیے ادا کرتے ہیں۔
ان سب پر حکمرانی کا ایک اصول: سیاق و سباق
واحد ذہنی ماڈل جس کی آپ کو ضرورت ہے۔
مخصوص استعمال کے معاملات کو دیکھنے سے پہلے اس واحد اصول کو اندرونی بنائیں۔ کیونکہ ایک بار جب آپ کے پاس اصول ہو جائیں تو زبان میں ڈاٹ مختصر کرنے کی تمام مثالیں واضح ہو جاتی ہیں۔
ڈاٹ مختصر کرنا صرف اس صورت میں کام کرتا ہے جب مرتب کرنے والا پہلے سے متوقع قسم کو جانتا ہو۔
یہ مکمل ضابطہ ہے۔ باقی سب کچھ اسی کا نتیجہ ہے۔
جب مرتب کرنے والا قسم جانتا ہے۔ .member فیصلہ کریں TypeName.member. ڈاٹ شارٹ ہینڈ ایک کمپائل ٹائم ایرر ہے اگر کمپائلر کو ٹائپ کا پتہ نہیں ہے۔ کوئی اندازہ نہیں، کوئی رن ٹائم انفرنس، کوئی ابہام نہیں۔ کمپائلر شارٹ ہینڈ کو کمپائل کے وقت حل کرتا ہے اسی قسم کی معلومات کا استعمال کرتے ہوئے جو اس کے پاس پہلے سے موجود ہے۔
آئیے ایک نظر ڈالتے ہیں کہ اس کا خاص طور پر کیا مطلب ہے۔
// The compiler knows the type from the variable declaration.
// NetworkStatus currentStatus = ...
// So .connecting is NetworkStatus.connecting. This works.
NetworkStatus currentStatus = .connecting;
// The compiler has no type context here.
// There is no surrounding variable, parameter, or declaration
// to tell it what type .connecting belongs to.
// This is a compile-time error.
var x = .connecting; // ERROR: No context type available
// The compiler knows the type from the parameter declaration.
// The parameter `status` is declared as NetworkStatus.
// So passing .connected resolves to NetworkStatus.connected. This works.
void update(NetworkStatus status) { }
update(.connected); // Works: parameter type provides context
NetworkStatus currentStatus = .connecting یہ واضح قسم کی تشریح کی وجہ سے کام کرتا ہے۔ NetworkStatus متغیر اعلامیہ وہ سب کچھ فراہم کرتا ہے جس کی کمپائلر کی ضرورت ہوتی ہے۔
var x = .connecting کیونکہ یہ ناکام ہو جاتا ہے۔ var اس کا مطلب ہے "دائیں سے اندازہ لگانا،” اور دائیں کا آغاز ڈاٹ شارٹ ہینڈ سے ہوتا ہے، جو خود بائیں کے سیاق و سباق کی ضرورت ہوتی ہے۔ یہ سرکلر ہے۔ کوئی سیاق و سباق نہیں ہے، لہذا کوئی مخففات نہیں ہیں۔
update(.connected) یہ فنکشن کے پیرامیٹر کی اقسام کی وجہ سے کام کرتا ہے۔ NetworkStatus یہ سیاق و سباق ہے۔
یہ ایک واحد بصیرت ہے جو پوری خصوصیت کی بنیاد کے طور پر کام کرتی ہے۔ اس ہینڈ بک میں موجود تمام درست اور غلط مثالیں ٹریک کرتی ہیں کہ آیا سیاق و سباق کی قسم اس مقام پر دستیاب ہے۔
گنتی: استعمال کے اہم معاملات
کیوں اینوم کو سب سے زیادہ فائدہ ہوتا ہے۔
دو وجوہات کی بنا پر ڈاٹ شارٹ ہینڈ کے لیے شماریات پہلے سے طے شدہ اور سب سے زیادہ تجویز کردہ استعمال کی صورت ہیں:
سب سے پہلے، یہ فلٹر میں ہر جگہ ظاہر ہوتا ہے، جس میں سیدھ، سائز، رنگ سکیمیں، ٹیکسٹ اوور فلو، فونٹ کا وزن، بٹن کے انداز، اور ایک درجن سے زیادہ چیزیں شامل ہیں۔ دوسرا، گنتی کی قدر کے لیے قسم کا سیاق و سباق تقریباً ہمیشہ واضح ہوتا ہے کہ اسے کیا تفویض کیا گیا ہے یا پیرامیٹر سیٹ کیا جا رہا ہے، تاکہ شارٹ کٹس زیادہ سے زیادہ واضح ہوں۔
تفویض
enum Status { idle, loading, success, error }
// Before Dart 3.10
Status currentStatus = Status.idle;
// With dot shorthands (Dart 3.10+)
Status currentStatus = .idle;
متغیر اعلان Status currentStatus سیاق و سباق کی قسم فراہم کرتا ہے۔ جب مرتب کرنے والا دائیں طرف جاتا ہے اور چیک کرتا ہے: .idleسیاق و سباق کی قسم (Status)، اس کی تصدیق کریں۔ Status نام کے ساتھ ایک رکن ہے۔ idleاظہار کی تشریح اس طرح کی جاتی ہے: Status.idle. نتیجے کے طور پر، مرتب کردہ کوڈ پچھلے ورژن سے مماثل ہے۔ رن ٹائم میں کوئی فرق نہیں ہے، صرف نحو کا فرق ہے۔
فلٹر ویجیٹ کے پیرامیٹرز
// Before Dart 3.10
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
)
// With dot shorthands (Dart 3.10+)
Column(
mainAxisAlignment: .center,
crossAxisAlignment: .start,
mainAxisSize: .min,
)
کہ Column ویجیٹ کا کنسٹرکٹر واضح طور پر اپنے پیرامیٹر کی اقسام کا اعلان کرتا ہے۔ mainAxisAlignment ہے MainAxisAlignment, crossAxisAlignment ہے CrossAxisAlignment, mainAxisSize ہے MainAxisSize. ہر پیرامیٹر ڈیکلریشن منظور شدہ دلائل کے لیے ایک سیاق و سباق کی قسم ہے۔ جب مرتب کرنے والا دیکھتا ہے۔ .center پر mainAxisAlignment مقام، سیاق و سباق کی قسم ہے۔ MainAxisAlignmentتو .center بن جاتا ہے۔ MainAxisAlignment.center. ہر شارٹ ہینڈ کو اس کے اپنے پیرامیٹرز کی اعلان کردہ قسم کا استعمال کرتے ہوئے آزادانہ طور پر حل کیا جاتا ہے۔
تین سطری ورژن اور نیا ورژن بالکل ایک ہی بائیک کوڈ پر مرتب کرتے ہیں۔ شارٹ ہینڈ ایک کمپائل ٹائم کنورژن ہے، رن ٹائم کنورژن نہیں۔
بہتر گنتی
ڈارٹ کی بہتر گنتی (ڈارٹ 2.17 میں متعارف کرائی گئی) میں فیلڈز، طریقے اور کنسٹرکٹرز ہو سکتے ہیں۔ ڈاٹ شارٹ ہینڈ گنتی کی قسم کے تمام مستحکم طور پر قابل رسائی اراکین پر کام کرتا ہے۔
enum Priority {
low(1),
medium(5),
high(10);
final int weight;
const Priority(this.weight);
static Priority fromWeight(int w) {
if (w <= 3) return low;
if (w <= 7) return medium;
return high;
}
}
// Dot shorthand on an enum value
Priority taskPriority = .high;
// Dot shorthand on a static factory method defined on the enum
Priority resolved = .fromWeight(8);
Priority taskPriority = .high متغیر کی اعلان کردہ قسم کو سیاق و سباق کے طور پر استعمال کرتا ہے۔ .high فیصلہ کریں Priority.high. Priority resolved = .fromWeight(8) کال جامد fromWeight طریقہ Priority قسم کے نام کے ہجے کے بغیر۔ دونوں کام کرتے ہیں کیونکہ متغیر کی قسم سیاق و سباق فراہم کرتی ہے۔
گنتی کی واپسی کی قسم کے ساتھ فنکشن کے اندر
Priority getDefaultPriority() {
return .medium; // return type provides context: Priority
}
اگر فنکشن کی اعلان کردہ واپسی کی قسم ایک گنتی کی قسم ہے۔ return ایک بیان کی قدر اس کے سیاق و سباق کے طور پر اس کی قسم ہے. .medium فیصلہ کریں Priority.medium اس کی وجہ یہ ہے کہ فنکشن کی واپسی کی قسم ہے: Priority. اسی کا اطلاق کسی بھی فنکشن، طریقہ، یا واضح واپسی کی قسم کے ساتھ حاصل کرنے والے پر ہوتا ہے۔
جامد فیلڈز اور مستقل
جامد مستقل
جامد مستقل، خاص طور پر سینٹینل اقدار جیسے Duration.zero, EdgeInsets.zeroاور Offset.zeroعام طور پر فلٹر اور ڈارٹ میں استعمال ہوتا ہے۔ ڈاٹ شارٹ ہینڈ کا استعمال چیزوں کو نمایاں طور پر صاف کرتا ہے۔
// Before Dart 3.10
Duration timeout = Duration.zero;
EdgeInsets padding = EdgeInsets.zero;
Offset position = Offset.zero;
// With dot shorthands (Dart 3.10+)
Duration timeout = .zero;
EdgeInsets padding = .zero;
Offset position = .zero;
ہر معاملے میں، متغیر کی اعلان کردہ قسم (Duration, EdgeInsets, Offset) سیاق و سباق ہے۔ .zero اسے مناسب قسم کے جامد سے تعبیر کیا جاتا ہے۔ zero یہ ہر معاملے میں مستقل ہے۔
یہ خاص طور پر مفید ہے کیونکہ صفر کی قدر والے سینٹینلز اکثر اینیمیشن کوڈ، لے آؤٹ کوڈ، اور جیومیٹرک حسابات میں ظاہر ہوتے ہیں، اصل کوڈ بیس میں تکرار کو بچاتے ہیں۔
بلٹ ان ڈارٹ اقسام سے جامد فیلڈز
ڈارٹ کی بلٹ ان اقسام جامد فیلڈز کو بھی بے نقاب کرتی ہیں اور اتنی ہی اچھی طرح سے کام کرتی ہیں۔
// Duration.zero is a static field on Duration
Duration animationDuration = .zero;
// double.infinity is a static field on double
double maxWidth = .infinity;
// String.isEmpty and similar static constants on types
int maxRetries = .maxFinite.toInt(); // double context, then chained
Duration animationDuration = .zero حل .zero پسند Duration.zero متغیر قسم میں۔ double maxWidth = .infinity حل .infinity پسند double.infinity. دوسری مثال ایک کنکشن کا آغاز بھی دکھاتی ہے، جو اس کے اپنے حصے میں شامل ہے۔
جامد طریقہ
شارٹ ہینڈ کا استعمال کرتے ہوئے جامد طریقوں کو کال کرنا
جامد طریقوں کو اسی طرح کہا جاتا ہے جیسے جامد فیلڈز۔ اس کے آگے ایک ڈاٹ ہے، اس کے بعد طریقہ کا نام اور دلائل ہیں۔ سیاق و سباق کی قسم مرتب کرنے والے کو بتاتی ہے کہ طریقہ کو کس کلاس میں تلاش کرنا ہے۔
// Before Dart 3.10
int port = int.parse('8080');
double ratio = double.parse('1.618');
DateTime now = DateTime.now();
// With dot shorthands (Dart 3.10+)
int port = .parse('8080');
double ratio = .parse('1.618');
DateTime now = .now();
int port = .parse('8080') فیصلہ کریں int.parse('8080') اس کی وجہ یہ ہے کہ متغیر کی اعلان کردہ قسم ہے: intاور int ایک جامد طریقہ ہے جسے کہا جاتا ہے۔ parse کہ String اور واپس int. double ratio = .parse('1.618') فیصلہ کریں double.parse('1.618') یہ ایک ہی طریقہ کار استعمال کرتا ہے۔ DateTime now = .now() فیصلہ کریں DateTime.now() پر DateTime سیاق و سباق
کسی طریقہ کی واپسی کی قسم سیاق و سباق کی قسم کے ساتھ ہم آہنگ ہونی چاہیے۔ اگر int.parse واپسی Stringکمپائلر ایک قسم کی خرابی کی اطلاع دیتا ہے۔ شارٹ ہینڈ ریزولوشن پہلے ہوتا ہے (سیاق و سباق کی قسم پر جامد ممبروں کو تلاش کرنا) اور نتیجہ سیاق و سباق کے خلاف معمول کے مطابق ٹائپ چیک کیا جاتا ہے۔
فنکشن کے دلائل میں
void configure({required Duration timeout, required int retryCount}) {}
configure(
timeout: .zero, // Duration context -> Duration.zero
retryCount: .parse('3'), // int context -> int.parse('3')
);
ہر نامزد دلیل کی اعلان کردہ پیرامیٹر کی قسم دلیل کی قدر کا سیاق و سباق ہے۔ timeout اس کا اعلان درج ذیل ہے: Durationتو .zero فیصلہ کریں Duration.zero. retryCount اس کا اعلان درج ذیل ہے: intتو .parse('3') فیصلہ کریں int.parse('3'). ہر دلیل کی مختصر شکل اس کے اپنے پیرامیٹر کی قسم کا استعمال کرتے ہوئے آزادانہ طور پر حل کی جاتی ہے۔
کنسٹرکٹرز اور نامزد کنسٹرکٹرز
نام کنسٹرکٹر
نامزد کنسٹرکٹرز ڈارٹ کے سب سے زیادہ محاوراتی نمونوں میں سے ایک ہیں۔ میں موجود ہیں۔ EdgeInsets, BorderRadius, Color, TextStyle, Durationاور درجنوں دوسری قسمیں ہیں جو ہر Flutter ایپ استعمال کرتی ہے۔ ڈاٹ شارٹ ہینڈ تمام کام اس طرح کرتا ہے:
// Before Dart 3.10
EdgeInsets padding = EdgeInsets.all(16);
BorderRadius radius = BorderRadius.circular(8);
Color accent = Color.fromARGB(255, 66, 133, 244);
TextStyle headline = TextStyle();
// With dot shorthands (Dart 3.10+)
EdgeInsets padding = .all(16);
BorderRadius radius = .circular(8);
Color accent = .fromARGB(255, 66, 133, 244);
TextStyle headline = TextStyle(); // still fine with full form too
EdgeInsets padding = .all(16) یہ کام کرتا ہے کیونکہ EdgeInsets سیاق و سباق کی قسم ہے اور .all(16) فیصلہ کریں EdgeInsets.all(16)یہ ایک نامزد کنسٹرکٹر ہے۔ BorderRadius radius = .circular(8) یہ اسی طرز کی پیروی کرتا ہے۔
ڈاٹ شارٹ ہینڈ ہمیشہ اختیاری ہوتا ہے، لہذا مکمل فارمیٹ اب بھی کام کرے گا۔ شارٹ ہینڈ کا انتخاب کریں اگر یہ پڑھنے کی اہلیت کو بہتر بناتا ہے، اور اگر قسم کے نام اسے واضح کرتے ہیں تو مکمل فارمیٹ رکھیں۔
ویجیٹ کنسٹرکٹر میں
نامزد کنسٹرکٹرز ویجیٹ کے پیرامیٹرز میں چمکتے ہیں جنہیں زیادہ تر فلٹر ڈویلپرز سب سے زیادہ استعمال کرتے ہیں۔
// Before Dart 3.10
Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey, width: 1),
),
child: Text('Hello'),
),
)
// With dot shorthands (Dart 3.10+)
Padding(
padding: .symmetric(horizontal: 16, vertical: 8),
child: Container(
decoration: BoxDecoration(
borderRadius: .circular(12),
border: .all(color: Colors.grey, width: 1),
),
child: Text('Hello'),
),
)
padding: .symmetric(horizontal: 16, vertical: 8) حل .symmetric(...) پسند EdgeInsets.symmetric(...) کیونکہ padding پیرامیٹر Padding اس کا اعلان درج ذیل ہے: EdgeInsets. borderRadius: .circular(12) یہ مندرجہ ذیل طور پر حل کیا جاتا ہے: BorderRadius.circular(12) کیونکہ borderRadius میدان BoxDecoration یہ درج ذیل ہے: BorderRadius?. border: .all(color: Colors.grey, width: 1) یہ مندرجہ ذیل طور پر حل کیا جاتا ہے: Border.all(...) کیونکہ border میدان BoxDecoration یہ درج ذیل ہے: BoxBorder?کوئی بھی Border اسے نافذ کریں۔
شارٹ ہینڈ ریزولیوشن ممبر کی جامد قسم کے ساتھ ساتھ اس کی صحیح اعلان شدہ قسم کی بھی جانچ کرتا ہے۔
.نیا مخفف
ڈیفالٹ کنسٹرکٹر کو کال کریں۔
ڈارٹ ClassName.new نامعلوم ڈیفالٹ کنسٹرکٹر کا ایک نامزد حوالہ۔ ڈاٹ شارٹ ہینڈ سپورٹ .new(args) ڈیفالٹ کنسٹرکٹر کو کال کرنے کے لیے شارٹ ہینڈ:
class AppConfig {
final String baseUrl;
final int timeout;
AppConfig(this.baseUrl, this.timeout);
}
// Before Dart 3.10
AppConfig config = AppConfig('https://api.example.com', 30);
// With dot shorthand using .new
AppConfig config = .new('https://api.example.com', 30);
.new('https://api.example.com', 30) فیصلہ کریں AppConfig.new('https://api.example.com', 30)یہ کال کرنے جیسا ہی ہے۔ AppConfig('https://api.example.com', 30). سیاق و سباق کی قسم AppConfig قرارداد متغیر اعلامیہ میں طے کی جاتی ہے۔
جب .new سب سے زیادہ مفید ہے۔
کہ .new شارٹ ہینڈ عام سیاق و سباق اور فنکشن آئسولیشن میں سب سے زیادہ مفید ہے جہاں کلاس کا نام کنسٹرکٹر حوالہ کے طور پر بیان کیا جانا چاہیے۔
ڈائریکٹ متغیر اسائنمنٹ کلاس کا نام ٹائپ کرنے پر زیادہ رقم نہیں بچاتی، کیونکہ کلاس کا نام پہلے سے ہی ٹائپ تشریح میں ہے۔ حقیقی فوائد درج ذیل نمونہ میں ظاہر ہوتے ہیں:
// A list of items where each item is constructed in place
List configs = [
.new('https://api.example.com', 30),
.new('https://staging.example.com', 60),
.new('https://dev.example.com', 120),
];
List آپ فہرست کے عنصر کی قسم کے ذریعے سیاق و سباق کی قسم فراہم کرتے ہیں۔ AppConfig. ہر ایک .new(...) لسٹ لٹریل کے اندر، یہ حل کرتا ہے: AppConfig(...). بہت سی ملتے جلتے کنسٹرکٹر کالوں والی فہرست میں، شارٹ ہینڈ دہرائے جانے والے قسم کے سابقے کو ہٹاتا ہے جو تمام اندراجات میں ظاہر ہوتے ہیں۔
شارٹ ہینڈ کے بعد کنکشن
مثال کا طریقہ کنکشن
ڈاٹ شارٹ ہینڈ کا مکمل اظہار ہونا ضروری نہیں ہے۔ جامد رسائی کے بعد، آپ انسٹینس میتھڈ کالز، پراپرٹی تک رسائی اور دیگر سلیکٹرز کو چین کر سکتے ہیں۔ زنجیر ضرورت کے مطابق لمبا ہو سکتا ہے، جب تک کہ حتمی نتیجہ کی قسم سیاق و سباق کے ساتھ مطابقت رکھتی ہو۔
// Chain an instance method after a static method call
int value = .parse(' 42 ').abs();
// Chain a property access after a constructor call
double distance = .fromARGB(255, 255, 0, 0).opacity;
// Chain a method after an enum value's instance method
String statusLabel = .loading.name.toUpperCase();
int value = .parse(' 42 ').abs() حل .parse(' 42 ') پسند int.parse(' 42 ')یہ ہے int. پھر .abs() اس کے بارے میں کہا جائے گا int مثال نتیجہ یہ ہے۔ intیہ متغیر کی اعلان کردہ قسم سے میل کھاتا ہے۔
مخفف صرف بڑے جامد رسائی پر لاگو ہوتا ہے۔ باقی سلسلہ باقاعدہ مثال کے ممبر تک رسائی ہے۔ String statusLabel = .loading.name.toUpperCase() شمار کی قدر سے تعلق کو ظاہر کرتا ہے۔ شارٹ ہینڈ ریزولوشن کے لئے سیاق و سباق کی قسم ایک گنتی ہے (یہاں: Status یا اسی طرح) .name تمام گنتی کی اقدار پر ایک بلٹ ان پراپرٹی جو قدر کا نام لوٹاتی ہے۔ Stringاور .toUpperCase() یہ ایک مثالی طریقہ ہے۔ String.
یہ کیوں اہمیت رکھتا ہے۔
کنکٹنیشن کا مطلب ہے کہ ڈاٹ شارٹ ہینڈ آپ کو کسی جامد ممبر پر رکنے پر مجبور نہیں کرتا ہے۔ اگر آپ کو نتیجہ کی خصوصیات کو تبدیل کرنے یا ان تک رسائی حاصل کرنے کی ضرورت ہے، تو آپ اسی اظہار کے ساتھ ایسا کر سکتے ہیں۔ قواعد درج ذیل ہیں: .member شارٹ ہینڈ ہے، اس کے بعد سب کچھ ایک عام مثال تک رسائی کا سلسلہ ہے۔
// Combining a static constructor call with a property read
Color primary = .fromARGB(255, 66, 133, 244);
double alpha = .fromARGB(255, 66, 133, 244).opacity; // context is double
Color primary = .fromARGB(255, 66, 133, 244) استعمال کریں Color شارٹ کٹس کو حل کرنے کے لیے سیاق و سباق۔ double alpha = .fromARGB(255, 66, 133, 244).opacity ہے double سیاق و سباق کی قسم نہیں۔ Color. اس کا مطلب ہے: .fromARGB اسے جامد طریقہ سے حل کیا جانا چاہئے۔ double کیا موجود ہے اور کیا نہیں ہے۔
یہ مخصوص مثال ناکام ہو جاتی ہے۔ سیاق و سباق کی قسم ترجیحی رسائی کو کنٹرول کرتی ہے، لہذا ترجیحی شارٹ ہینڈ کا سیاق و سباق یہ ہے: doubleنہیں Color. یہ ایک لطیف نکتہ ہے۔ زنجیر بناتے وقت، اس بات کو یقینی بنائیں کہ ایکسپریشن پوزیشن کے سیاق و سباق کی قسم ہدف کی قسم سے مماثل ہے۔
مساوات آپریٹر: خصوصی قواعد
== اور != ڈاٹ شارٹ ہینڈ استعمال کرنے کا طریقہ
کہ == اور != آپریٹرز کے پاس پوائنٹ عرفی ناموں کے لیے خاص اصول ہوتے ہیں جو عام سیاق و سباق کے قواعد سے مختلف ہوتے ہیں۔ جب دائیں طرف ڈاٹ کا مخفف ظاہر ہوتا ہے۔ == یا != اظہار میں، سیاق و سباق کی قسم بائیں طرف کی جامد قسم سے اخذ کی گئی ہے، ارد گرد کے متغیر یا پیرامیٹر سے نہیں۔
enum Color { red, green, blue }
Color myColor = Color.red;
// The LHS is myColor, which has static type Color.
// So .green is resolved as Color.green.
if (myColor == .green) {
print('The color is green.');
}
// Works the same with !=
if (myColor != .blue) {
print('The color is not blue.');
}
myColor == .green یہ کام کرتا ہے کیونکہ myColor اس کا اعلان درج ذیل ہے: Colorبنانا Color سیاق و سباق دائیں طرف .green. مرتب کرنے والا اسے حل کرتا ہے۔ .green پسند Color.green مساوات کا موازنہ کرنے سے پہلے۔
یہاں یہ خاص اصول کیوں موجود ہے: == اظہارات میں متغیر اسائنمنٹس کی طرح آس پاس کے سیاق و سباق کی قسم نہیں ہوتی ہے۔ اس کے بجائے بائیں طرف استعمال کیا جاتا ہے۔
مشروط اظہار کی مساوات
Color selectedColor = Color.red;
bool condition = true;
Color inferredColor = condition ? .red : .blue;
Color inferredColor = condition ? .red : .blue دونوں حل .red اور .blue پسند Color قدر ٹرنری ایکسپریشن کی سیاق و سباق کی قسم اسائنمنٹ ٹارگٹ کی قسم سے آتی ہے۔ Color. ٹرنری کی دونوں شاخیں ایک ہی سیاق و سباق کی قسم حاصل کرتی ہیں، لہذا دونوں شارٹ کٹس کو صحیح طریقے سے حل کیا جاتا ہے۔
جو کام نہیں کرتا
// ERROR: No context for the shorthand on the right side
// because the left side is `var`, which has no known type yet.
var isMatch = someValue == .green; // FAILS if someValue's type is not clear
// This works if someValue is explicitly typed
Color someValue = Color.blue;
bool isMatch = someValue == .green; // Works: someValue is Color
var isMatch = someValue == .green جب آپ ناکام ہوجاتے ہیں۔ someValueہم آپ کا اندازہ لگانے سے پہلے آپ کی قسم کا اندازہ نہیں لگا سکتے۔ قواعد کا انحصار بائیں جانب جامد قسم پر ہوتا ہے، جو مرتب وقت پر جانا جاتا ہے۔ اگر مرتب کرنے والا بائیں ہاتھ کی قسم کا تعین نہیں کرسکتا ہے تو، مخفف کا کوئی سیاق و سباق نہیں ہے جس کی جانچ کی جائے۔
بیانات اور پیٹرن کے ملاپ کو تبدیل کریں۔
گنتی آن کریں۔
اعداد و شمار کی قدروں کے لیے سوئچ اسٹیٹمنٹس وہ جگہ ہیں جہاں ڈاٹ شارٹ ہینڈ اصل کوڈ میں پڑھنے کی اہلیت میں سب سے زیادہ ڈرامائی بہتری فراہم کرتا ہے۔ سوئچ ٹارگٹ ٹائپ کو تمام کیس پیٹرن کے سیاق و سباق کے طور پر استعمال کیا جاتا ہے۔
enum AppState { loading, loaded, error, empty }
AppState state = .loading;
// Before Dart 3.10
switch (state) {
case AppState.loading:
return const CircularProgressIndicator();
case AppState.loaded:
return const ContentWidget();
case AppState.error:
return const ErrorWidget();
case AppState.empty:
return const EmptyStateWidget();
}
// With dot shorthands (Dart 3.10+)
switch (state) {
case .loading:
return const CircularProgressIndicator();
case .loaded:
return const ContentWidget();
case .error:
return const ErrorWidget();
case .empty:
return const EmptyStateWidget();
}
state اس کا اعلان درج ذیل ہے: AppStateبنانا AppState سوئچ کے تمام معاملات کے لیے سیاق و سباق کی قسم۔ ہر ایک .loading, .loaded, .errorاور .empty قابل اطلاق حل۔ AppState قدر سوئچ مکمل ہے. ٹیسٹنگ اسی طرح کام کرتی ہے۔ مرتب کرنے والا اب بھی اس بات کو یقینی بناتا ہے کہ گنتی کی تمام مثالیں شامل ہیں۔
اظہار سوئچ کریں
ڈارٹ کے سوئچ ایکسپریشنز (اظہار کی قسمیں جو قدر واپس کرتی ہیں) ایک ہی کام کرتی ہیں۔
Widget content = switch (state) {
.loading => const CircularProgressIndicator(),
.loaded => const ContentWidget(),
.error => const ErrorWidget(),
.empty => const EmptyStateWidget(),
};
switch (state) کہاں state ہے AppState فراہم کرتا ہے AppState بائیں طرف ہر پیٹرن کے سیاق و سباق کے طور پر =>. ہر ایک .loading, .loaded, .errorاور .empty قابل اطلاق حل۔ AppState قدر ہر ایک کے دائیں طرف => تیر سوئچ سیاق و سباق سے متاثر نہیں ہوتے ہیں۔ ہر ایک => شاخ ایک باقاعدہ اظہار ہے۔
سوئچز کا پیٹرن ملاپ
void handleResult(Result result) {
switch (result) {
case .success when result.value > 0:
print('Positive success: ${result.value}');
case .success:
print('Non-positive success');
case .failure:
print('Failed: ${result.error}');
}
}
تحفظ کی شق (when) ڈاٹ شارٹ ہینڈ کے ساتھ قدرتی طور پر کام کرتا ہے۔ .success when result.value > 0 گنتی کی اقدار کے لیے کیس پیٹرن۔ Result.success اضافی تحفظ کی شرائط ہیں۔ شارٹ ہینڈز کو مماثل مقاصد کے لیے گنتی کی اقدار کے لیے حل کیا جاتا ہے، اور گارڈز کا الگ سے جائزہ لیا جاتا ہے۔
nullable قسم
ممبر تک رسائی T کے ذریعے T?
اگر متغیر یا پیرامیٹر میں کالعدم قسم ہے۔ T?آپ اب بھی بنیادی اقسام کے جامد اراکین تک رسائی کے لیے ڈاٹ مخففات استعمال کر سکتے ہیں۔ T. ڈارٹ تفصیلات واضح طور پر اجازت دیتا ہے:
// A parameter typed as nullable Status
void updateStatus(Status? newStatus) {
// You can pass a non-null Status value using a shorthand
}
updateStatus(.loading); // passes Status.loading, which is a valid Status?
updateStatus(.loading) یہ پیرامیٹر کی قسم کی وجہ سے کام کرتا ہے۔ Status? کے لیے سیاق و سباق فراہم کرتا ہے۔ Status?ڈاٹ شارٹ ہینڈ رولز کا استعمال کرتے ہوئے، آپ درج ذیل ممبران تک رسائی حاصل کر سکتے ہیں: Status کو Status? سیاق و سباق قدر .loading فیصلہ کریں Status.loadingیہ کالعدم نہیں ہے۔ Statusغیر null اقدار ہمیشہ nullable پوزیشنوں میں درست ہوتی ہیں۔
nullable متغیرات کو تفویض کرنا
Status? maybeStatus = .error; // Assigns Status.error to a Status? variable
Status? nothing = null; // Still works; null is valid for Status?
Status? maybeStatus = .error حل .error پسند Status.error (میں Status? سیاق و سباق)، جو ایک nullable متغیر کو تفویض کیا گیا ہے۔ کسی قسم کی منسوخی شارٹ ہینڈ کو کام کرنے سے نہیں روکتی ہے۔ اس کا مطلب صرف یہ ہے کہ متغیر null رکھ سکتا ہے۔ شارٹ ہینڈ ہمیشہ بنیادی قسم کی غیر null قدر پیدا کرتا ہے۔
کیا منسوخ ہونے والا سیاق و سباق عطا نہیں کرتا ہے۔
ایک کالعدم سیاق و سباق آپ کو درج ذیل اراکین تک رسائی فراہم کرتا ہے: Tلیکن کا رکن نہیں۔ Null. Null اس مقصد کے لیے کوئی جامد ممبران کارآمد نہیں ہیں اور فنکشن اسے بے نقاب نہیں کرتا ہے۔
// This resolves to Duration.zero (from the Duration? context's underlying Duration type)
Duration? elapsed = .zero;
// You cannot access static members of Null through a nullable context
// There are no meaningful Null static members to access
Duration? elapsed = .zero حل .zero پسند Duration.zero پر Duration? سیاق و سباق جامد ممبر کی تلاش کے لیے کالعدم ریپر شفاف ہے۔
FutureOr اور Async کو واپس کریں۔
غیر مطابقت پذیر فنکشن سے قدر واپس کرنا
اندرونی async فنکشن، کسی بھی موثر واپسی کی قسم return بیان ہے۔ FutureOr کہاں T اعلان کردہ واپسی کی قسم۔ ڈاٹ مختصر کرنے کی تصریح اس معاملے کو واضح طور پر اجازت دے کر سنبھالتی ہے: Tآپ کے جامد ممبران تک رسائی حاصل کر سکتے ہیں۔ FutureOr سیاق و سباق:
Future fetchStatus() async {
// The function's declared return type is Future.
// Inside an async function, return accepts a FutureOr.
// Dot shorthand resolves .loaded as Status.loaded.
return .loaded;
}
return .loaded میں Future غیر مطابقت پذیر فنکشن کام کرتے ہیں کیونکہ غیر مطابقت پذیر فنکشن کا واپسی سیاق و سباق یہ ہے: FutureOrڈاٹ شارٹ ہینڈ قواعد کا استعمال رسائی کی اجازت دیتا ہے۔ Status ممبران FutureOr سیاق و سباق
ڈارٹ ٹیم نے خاص طور پر اس کیس کی حمایت کرنے کا فیصلہ کیا کیونکہ غیر مطابقت پذیر فنکشنز سے خالص اقدار کی واپسی بہت عام اور انتہائی مطالبہ ہے۔ Status.loaded اگر فنکشن کی واپسی کی قسم پہلے سے ہی ہے: Status اسے غیر ضروری زبانی سمجھا جاتا تھا۔
FutureOr غیر async سیاق و سباق میں
FutureOr getDelay() {
// Can return either a Duration or a Future
return .zero; // Resolves to Duration.zero
}
return .zero ایک فنکشن میں جو واپس آتا ہے۔ FutureOr حل .zero پسند Duration.zero کیونکہ FutureOr سیاق و سباق اس تک رسائی فراہم کرتا ہے: Durationکا ممبر ہے واپسی ہوئی قدر ہم وقت ساز ہے۔ Durationیہ درست ہے۔ FutureOr.
حقیقی تبدیلی
فلٹر ویجیٹ ٹری ڈاٹ شارٹ ہینڈ کو عمل میں دیکھنے کے لئے سب سے زیادہ بااثر جگہ ہے کیونکہ اس میں تمام فلٹر کوڈ بیس میں گنتی کی قدروں اور نامزد کنسٹرکٹرز کی سب سے بڑی تعداد شامل ہے۔
یہاں حقیقت پسندانہ پروفائل کارڈ ویجیٹ سے پہلے اور بعد میں ہے۔
// Before Dart 3.10: A profile card widget
class ProfileCard extends StatelessWidget {
final String name;
final String role;
final bool isOnline;
const ProfileCard({
super.key,
required this.name,
required this.role,
required this.isOnline,
});
@override
Widget build(BuildContext context) {
return Card(
elevation: 2,
child: Padding(
padding: EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CircleAvatar(
backgroundColor: isOnline ? Colors.green : Colors.grey,
radius: 24,
child: Text(
name[0].toUpperCase(),
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(width: 12),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: TextStyle(
fontWeight: FontWeight.w600,
overflow: TextOverflow.ellipsis,
),
),
Text(
role,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
],
),
),
Icon(
isOnline ? Icons.circle : Icons.circle_outlined,
color: isOnline ? Colors.green : Colors.grey,
size: 12,
),
],
),
),
);
}
}
یہ صاف، محاورہ فلٹر کوڈ ہے۔ لیکن دیکھو کہ یہ کتنی تکرار ہے۔ تمام گنتی کی اقدار اور تمام کنسٹرکٹر کالز کے لیے مکمل قسم کا نام۔
اب یہی بات شارٹ ہینڈ کے لیے بھی سچ ہے۔
// With dot shorthands (Dart 3.10+)
class ProfileCard extends StatelessWidget {
final String name;
final String role;
final bool isOnline;
const ProfileCard({
super.key,
required this.name,
required this.role,
required this.isOnline,
});
@override
Widget build(BuildContext context) {
return Card(
elevation: 2,
child: Padding(
padding: .all(16),
child: Row(
mainAxisAlignment: .start,
crossAxisAlignment: .center,
children: [
CircleAvatar(
backgroundColor: isOnline ? Colors.green : Colors.grey,
radius: 24,
child: Text(
name[0].toUpperCase(),
style: TextStyle(
color: Colors.white,
fontWeight: .bold,
),
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
mainAxisSize: .min,
crossAxisAlignment: .start,
children: [
Text(
name,
style: TextStyle(
fontWeight: .w600,
overflow: .ellipsis,
),
),
Text(
role,
style: TextStyle(
color: Colors.grey,
fontSize: 12,
),
),
],
),
),
Icon(
isOnline ? Icons.circle : Icons.circle_outlined,
color: isOnline ? Colors.green : Colors.grey,
size: 12,
),
],
),
),
);
}
}
padding: .all(16) فیصلہ کریں EdgeInsets.all(16) کیونکہ Padding.padding داخل کیا گیا ہے EdgeInsets. mainAxisAlignment: .start فیصلہ کریں MainAxisAlignment.start کیونکہ Row.mainAxisAlignment داخل کیا گیا ہے MainAxisAlignment. crossAxisAlignment: .center فیصلہ کریں CrossAxisAlignment.center. fontWeight: .bold فیصلہ کریں FontWeight.bold کیونکہ TextStyle.fontWeight ہے FontWeight?. mainAxisSize: .min فیصلہ کریں MainAxisSize.min. overflow: .ellipsis فیصلہ کریں TextOverflow.ellipsis.
ہر مختصر فارم کا تعین اس کے ڈیکلریشن پیرامیٹر کی قسم سے ہوتا ہے۔
پہلے اور بعد میں ایک ہی مرتب شدہ آؤٹ پٹ تیار کرتے ہیں۔ فرق خالصتاً ماخذ کو پڑھنے کے طریقے میں ہے۔ شارٹ کٹ اس بات کو یقینی بناتے ہیں کہ پیرامیٹر کے نام اور اقدار ملحقہ ہیں اور آنکھ کو بار بار قسم کے ناموں سے گزرے بغیر ایک جگہ سے دوسری جگہ صاف طور پر جانے کی اجازت دیتے ہیں۔
اعلی درجے کے تصورات
اگر اندازہ شروع نہیں ہوتا ہے۔
ناکامی کی کہانیوں کو سمجھنا اتنا ہی اہم ہے جتنا کہ کامیابی کی کہانیوں کو سمجھنا۔ درج ذیل حالات ڈاٹ شارٹ ہینڈ کی حمایت نہیں کرتے ہیں کیونکہ وہ سیاق و سباق کی قسم فراہم نہیں کرتے ہیں۔
// var infers from the RHS, but RHS needs LHS context: circular, fails
var status = .loading; // ERROR
// The list literal does not know its element type from a leading dot
var items = [.loading, .error]; // ERROR: var provides no context
// Explicitly typed list works fine
List items = [.loading, .error]; // Works
// Dynamic removes type information entirely
dynamic value = .loading; // ERROR: dynamic is not a usable context type
// Conditional assignment where context is ambiguous
Object status = condition ? .loading : 'string'; // ERROR: Object too broad
var status = .loading کیونکہ یہ ناکام ہو جاتا ہے۔ var اس کا مطلب ہے کہ قسم کا اندازہ دائیں سے لگایا جاتا ہے، لیکن دائیں (مخفف) کو سیاق و سباق کے لیے بائیں قسم کی ضرورت ہوتی ہے۔ یہ سرکلر ہے۔
var items = [.loading, .error] یہ اسی وجہ سے ناکام ہوجاتا ہے۔ فہرست کے عناصر کی قسم اس کے مواد سے آتی ہے، لیکن مواد کو عنصر کی قسم کی ضرورت ہوتی ہے۔
List واضح قسم کی تشریحات مرتب کرنے والے کو بتاتی ہیں۔ Status فہرست کے عناصر کا جائزہ لینے سے پہلے سیاق و سباق کو چیک کریں۔
لیکن dynamic value = .loading کیونکہ یہ ناکام ہو جاتا ہے۔ dynamic یہ قسم کے نظام کو نظرانداز کرتا ہے اور ایک مستحکم سیاق و سباق کی قسم فراہم نہیں کرتا ہے جسے ممبر تلاش کرنے کے لیے استعمال کیا جا سکتا ہے۔
نیسٹڈ شارٹ ہینڈ
"نیسٹڈ شارٹ ہینڈ" تب ہوتا ہے جب آپ ڈاٹ شارٹ ہینڈ استعمال کرنے والے اظہار کے اندر ڈاٹ شارٹ ہینڈ استعمال کرنے کی کوشش کرتے ہیں۔ بیرونی شارٹ ہینڈ کی ریزولیوشن اپنی قسم کو اس سیاق و سباق میں نہیں پھیلاتی ہے جہاں یہ گھونسلہ ہے۔
// The outer shorthand resolves from the BoxDecoration context
BoxDecoration decoration = BoxDecoration(
borderRadius: .circular(8), // Outer shorthand: BorderRadius.circular(8)
border: .all( // Outer shorthand: Border.all(...)
color: Colors.grey,
width: 1,
),
);
یہ کام کرتا ہے۔ ہر شارٹ ہینڈ کو آزادانہ طور پر حل کیا جاتا ہے۔ .circular(8) پر BorderRadius? سیاق و سباق boxDecoration.borderRadiusاور .all(...) پر BoxBorder? سیاق و سباق boxDecoration.border. وہ اس معنی میں اوورلیپ نہیں ہوتے ہیں کہ وہ ایک دوسرے پر انحصار کرتے ہیں۔
واقعی نیسٹڈ شارٹ ہینڈ ایک اور شارٹ ہینڈ کال کے دلائل کے اندر شارٹ ہینڈ استعمال کرنا ہے۔
// Attempting to use a shorthand inside another shorthand's arguments
EdgeInsets padding = .fromLTRB(
.zero.left, // ERROR: .zero has no context here
8, 8, 8,
);
.zero.left کیونکہ یہ ناکام ہو جاتا ہے۔ .zero دلیل کے اندر .fromLTRB سیاق و سباق کی کوئی قائم کردہ قسم نہیں ہے۔ DCM لنٹر فراہم کرتا ہے: avoid-nested-shorthands یہ اصول ہے جو ان مقدمات کو جھنڈا دیتا ہے۔ ترمیمات کو ہمیشہ اندرونی مقامات پر واضح ہونا چاہیے جہاں سیاق و سباق غیر واضح ہو۔
EdgeInsets padding = .fromLTRB(
EdgeInsets.zero.left, // Explicit: fine
8, 8, 8,
);
توسیعی اقسام کا استعمال کرتے ہوئے ڈاٹ شارٹ ہینڈ
ایکسٹینشن کی قسمیں (Dart 3.3 میں متعارف کرائی گئی ہیں) ڈاٹ شارٹ ہینڈ کو بھی سپورٹ کرتی ہیں۔ اگر ایکسٹینشن کی قسم میں جامد اراکین ہیں، تو ان تک شارٹ ہینڈ کے طور پر رسائی حاصل کی جا سکتی ہے جب ایکسٹینشن کی قسم سیاق و سباق ہو۔
extension type Milliseconds(int value) {
static Milliseconds get zero => Milliseconds(0);
static Milliseconds fromSeconds(int seconds) => Milliseconds(seconds * 1000);
}
Milliseconds delay = .zero; // Milliseconds.zero
Milliseconds timeout = .fromSeconds(5); // Milliseconds.fromSeconds(5)
Milliseconds delay = .zero حل .zero پسند Milliseconds.zero متغیر کی اعلان کردہ قسم میں۔ Milliseconds timeout = .fromSeconds(5) جامد فیکٹری طریقوں کو حل کریں۔ Milliseconds.
اگرچہ ایکسٹینشن کی اقسام اب بھی نسبتاً نئی ہیں، ڈاٹ شارٹننگ کے لیے سپورٹ کا مطلب یہ ہے کہ آپ ایک ہی شارٹ ہینڈ فرینڈلی سٹیٹک ممبر API کا استعمال کرتے ہوئے ایکسٹینشن کی قسمیں ڈیزائن کر سکتے ہیں جیسا کہ بلٹ ان اقسام۔
لنٹر سپورٹ
ڈارٹ کوڈ میٹرکس (DCM) ٹول چار لِنٹ اصول فراہم کرتا ہے خاص طور پر ڈاٹ شارٹ ہینڈ کے لیے مسلسل اپنانے کو نافذ کرنے میں مدد کرتا ہے۔
# analysis_options.yaml (using DCM)
dcm:
rules:
- prefer-shorthands-with-enums
- prefer-shorthands-with-static-fields
- prefer-returning-shorthands
- prefer-shorthands-with-constructors:
entries:
- EdgeInsets
- BorderRadius
- Radius
- Border
- Duration
- avoid-nested-shorthands
prefer-shorthands-with-enums جھنڈے گنتی کی اقدار تک رسائی حاصل کرتے ہیں جہاں قسم کا نام رد کیا جا سکتا ہے کیونکہ اسے سیاق و سباق سے الگ کیا جاتا ہے۔ prefer-shorthands-with-static-fields جامد فیلڈ تک رسائی کے لئے بھی یہی ہے۔ prefer-returning-shorthands جھنڈا ایک بیان واپس کرتا ہے جو قسم کے نام کو ختم کرنے کی اجازت دیتا ہے۔ prefer-shorthands-with-constructors اور entries فہرست مخصوص کلاسوں کو جھنڈا دیتی ہے جن کے نام کنسٹرکٹر کالز شارٹ ہینڈ استعمال کرسکتے ہیں۔ avoid-nested-shorthands یہ اوپر بیان کردہ مسئلے کے ساتھ ایک نیسٹڈ کیس کو ظاہر کرتا ہے۔
ان اصولوں کو بتدریج فعال کریں، اس کے ساتھ شروع کریں: prefer-shorthands-with-enumsسب سے زیادہ مؤثر) موجودہ کوڈ بیسز کے لیے تجویز کردہ نقل مکانی کی حکمت عملی ہے۔
بہترین طرز عمل
Enum اور سوئچ اسٹیٹمنٹ کے ساتھ شروع کریں۔
ڈاٹ شارٹ ہینڈ کو اپنانے کے لیے سب سے زیادہ قدر اور سب سے کم خطرے کی جگہیں شمار کی اسائنمنٹس اور سوئچ کیس پیٹرن ہیں۔ یہ تب ہوتا ہے جب قسم کا سیاق و سباق تمام قارئین کے لیے سب سے زیادہ واضح ہوتا ہے، مرتب کرنے والے کا استدلال سب سے زیادہ قابل اعتماد ہوتا ہے، اور یہ سب سے زیادہ پڑھنے کے قابل ہوتا ہے۔ پہلے اپنے موجودہ کوڈ بیس سے ہجرت کریں۔
اگر قسم واقعی واضح نہیں ہے، تو ہمیشہ مکمل فارمیٹ رکھیں۔
ڈاٹ شارٹ ہینڈ کا مقصد شور کو کم کرنا ہے، ابہام پیدا کرنا نہیں۔ اگر کسی مخفف کی وجہ سے قاری توقف کرتا ہے اور سوچتا ہے کہ ڈاٹ کس قسم کا حوالہ دیتا ہے تو مکمل فارم استعمال کریں۔
مخصوص اشارے: اگر آپ کو اپنے IDE میں کسی اظہار پر منڈلانے کی ضرورت ہے یہ دیکھنے کے لیے کہ یہ کس قسم کا حل کرتا ہے، مکمل فارمیٹ زیادہ معنی خیز ہے۔
// Clear: the parameter name `alignment` tells you the type
alignment: .centerLeft,
// Less clear in isolation: what type does .fromARGB belong to?
// The full form communicates more clearly here
color: Color.fromARGB(255, 66, 133, 244), // more readable than .fromARGB
alignment: .centerLeft کیونکہ پیرامیٹر کے نام واضح ہیں۔ alignment سختی سے مطلب Alignment. Color.fromARGB(...) اس سے پڑھنا آسان ہے: .fromARGB(...) کیونکہ fromARGB اس کی وجہ یہ ہے کہ طریقہ کا نام واضح طور پر اس بات کی نشاندہی نہیں کرتا ہے کہ یہ کس قسم سے آیا ہے۔ Color اس کے سامنے ہونے سے تمام ابہام فوراً دور ہو جاتے ہیں۔
فائلوں یا ٹیموں میں مستقل مزاجی کو برقرار رکھیں
عدم مطابقت مستقل اپنانے یا مستقل اجتناب سے بدتر ہے۔ اگر آپ کا آدھا ویجیٹ ٹری مختصر شکل استعمال کرتا ہے اور آدھا مکمل فارم استعمال کرتا ہے، تو آپ کا کوڈ متضاد نظر آئے گا اور طرزیں مخلوط ہو جائیں گی، جس سے علمی بوجھ پیدا ہوگا۔
ایسے قوانین کا انتخاب کریں جو آپ کی ٹیم کے مطابق ہوں۔ گنتی کے لیے مخففات کو اپنائیں اور کنسٹرکٹرز کے لیے ان سے بچیں، یا انہیں بورڈ میں ان اقسام کے لیے اپنائیں جہاں پیرامیٹر کے نام قسم کو غیر واضح بناتے ہیں۔
شارٹ ہینڈ استعمال کرنے سے پہلے pubspec.yaml کو اپ ڈیٹ کریں۔
یہ خصوصیت زبان کے ورژن کے لحاظ سے محدود ہے۔ کسی ایسے پروجیکٹ میں فائلوں پر شارٹ کٹس کا استعمال جس نے SDK کی رکاوٹوں کو اپ ڈیٹ نہیں کیا ہے اس کے نتیجے میں تالیف کی خرابی ہوگی۔
نحو کو اپنانے سے پہلے رکاوٹوں کو اپ ڈیٹ کریں۔
environment:
sdk: ^3.10.0
sdk: ^3.10.0 مطلب "Dart 3.10.0 یا بعد کے پیچ یا معمولی ورژن (لیکن 4.0 یا بعد کے نہیں)"۔ یہ ڈارٹ 3 پروجیکٹس کے لیے ایک معیاری رکاوٹ ہے۔ اگر آپ کی ٹیم کے پاس ایک ہی ذخیرہ ہے جس میں ایک سے زیادہ پیکجز ہیں، ہر پیکج کا pubspec.yaml ڈاٹ شارٹ ہینڈ استعمال کرنے کے لیے اس پیکیج کے لیے خود اپ ڈیٹ شدہ رکاوٹوں کی ضرورت ہوتی ہے۔
ڈاٹ شارٹ ہینڈ کب استعمال کریں اور کب استعمال نہ کریں۔
جب ڈاٹ شارٹ ہینڈ یقینی طور پر صحیح انتخاب ہے۔
Flutter ویجیٹ پیرامیٹرز میں Enum اقدار ایک معیاری استعمال کی صورت ہے۔ mainAxisAlignment: .center, crossAxisAlignment: .start, mainAxisSize: .min, textAlign: .left یہ سب واضح ہے، پہلے سے ہی گہرے ویجیٹ درخت میں کافی افقی جگہ بچاتا ہے، اور کوڈ کو قدرتی طور پر پڑھنے کے قابل بناتا ہے۔
شماریات میں بیانات کو تبدیل کرنا دوسرا معیاری معاملہ ہے۔ ٹائپ شدہ اینوم متغیرات پر سوئچ کی تمام مثالیں مختصر شکل اختیار کر سکتی ہیں، اور نتیجہ ایک سوئچ اسٹیٹمنٹ ہے جو پہلے سے طے شدہ قسم کی قدر کے جوڑوں کی فہرست کے بجائے اقدار کی فہرست پڑھتا ہے۔
مشہور چوکیدار جیسے .zero, .empty, .none وہ اقسام جن کے اراکین کو عالمی طور پر سمجھا جاتا ہے وہ بھی اچھے امیدوار ہیں۔ Duration timeout = .zero واضح Duration timeout = Duration.zero کیونکہ سیاق و سباق کی اقسام ہیں اور zero یہ ایک عالمی طور پر سمجھا جانے والا چوکیدار ہے۔
جہاں مکمل فارمیٹ کو ترجیح دیں۔
کنسٹرکٹر یا سٹیٹک میتھڈ کالز جہاں طریقہ کا نام واضح طور پر ٹائپ کی نشاندہی نہیں کرتا ہے وہ مکمل قسم کے کیسز ہیں۔ .fromARGB(255, 66, 133, 244) یہ خود وضاحتی نہیں ہے۔ Color.fromARGB(255, 66, 133, 244). واضح قسم کے نام دستاویزات کے طور پر کام کرتے ہیں۔
کوئی بھی سیاق و سباق جہاں ایک نیا ڈویلپر نہ جانتا ہو کہ وہ کس قسم کو دیکھ رہے ہیں مکمل فارمیٹ استعمال کرنے کے قابل ہے۔ جب پیرامیٹر کا نام بیان کیا جاتا ہے۔ config قسم صارف کی وضاحت شدہ کلاس ہے۔ ServerConfigتحریر .defaults() سے کم واضح ServerConfig.defaults() کیونکہ config یہ ایک مبہم نام ہے اور شارٹ ہینڈ اس کلاس کو چھپاتا ہے جسے فوری کیا جا رہا ہے۔
اگر دو مختلف اقسام کے ایک ہی نام کے ساتھ جامد ارکان ہیں، اور دونوں کے سیاق و سباق کی قسم ہونے کا امکان ہے، تو آپ کو الجھن کو ختم کرنے کے لیے مکمل قسم کا استعمال کرنا چاہیے۔ یہاں تک کہ اگر مرتب کرنے والا غیر مبہم ہے، انسانی قاری نہیں ہوسکتا ہے۔
عام غلطیاں
واضح قسم کے بجائے var استعمال کریں۔
ڈیوی ایشن میں سب سے عام ابتدائی غلطی ڈیوی ایشن سٹینوگرافی کو استعمال کرنے کی کوشش کرنا ہے۔ var:
// ERROR: var cannot provide a context type
var status = .loading;
// CORRECT: explicit type annotation provides the context
Status status = .loading;
var status = .loading ایسا لگتا ہے کہ اسے کام کرنا چاہئے۔ کیونکہ var بالآخر، یہ مندرجہ ذیل کے طور پر اخذ کیا جاتا ہے. Status اگر آپ تفویض کریں۔ Status قدر لیکن inference کے لیے ٹائپ کریں۔ var یہ پہلے دائیں دیکھ کر کام کرتا ہے، اور آپ کو دائیں (مخفف) کو حل کرنے کے لیے بائیں قسم کی ضرورت ہوتی ہے۔
var تشخیص سے پہلے کوئی قسم فراہم نہیں کی جاتی ہے۔ تشخیص کے نتائج پر عمل کریں۔ حل یہ ہے کہ ہمیشہ واضح قسم کی تشریحات شامل کریں۔ یہ ایک لفظ میں بدل جاتا ہے، جس کے نتیجے میں کلینر کوڈ ہوتا ہے۔
اگر آپ SDK رکاوٹوں کو اپ ڈیٹ کرنا بھول جاتے ہیں۔
# BEFORE: Will not support dot shorthands
environment:
sdk: ^3.9.0
# AFTER: Enables dot shorthands for all files in this package
environment:
sdk: ^3.10.0
استعمال کرنے کی کوشش کر رہے ہیں۔ .loading یا پچھلے رکاوٹ کے ساتھ کسی پروجیکٹ میں کوئی دوسرا مخفف زبان کے ورژن کی طرف اشارہ کرتے ہوئے تالیف کی غلطی پیدا کرے گا۔ حل اپ ڈیٹ کرنا ہے: sdk فارماسیوٹیکل pubspec.yamlپھر بھاگو flutter pub get یا dart pub get. اس کے بعد کوڈ میں کسی تبدیلی کی ضرورت نہیں ہے۔ pubspec.yaml فیچر کو چالو کرنے کے لیے براہ کرم اپ ڈیٹ کریں۔
فرض کرنا شارٹ ہینڈ عام قسم کے دلائل کے اندر کام کرتا ہے۔
// ERROR: Type arguments do not provide a shorthand context
List<.center> items; // Meaningless and invalid
Map cache; // Invalid
قسم دلیل کی پوزیشن ( (باقاعدہ اقسام میں) اظہار کی پوزیشن نہیں ہے۔ ڈاٹ شارٹ ہینڈ پر مشتمل نہیں ہو سکتا۔
ڈاٹ شارٹ ہینڈ قدر کا اظہار ہونا چاہیے، قسم کا اظہار نہیں۔ یہ فرق ایک بار بیان کرنے کے بعد واضح ہے، لیکن یہ ان ڈویلپرز کو الجھا سکتا ہے جو صرف اس بات کی عادت ڈال رہے ہیں کہ شارٹ ہینڈ کا اطلاق کس حد تک ہوتا ہے۔
شارٹ ہینڈ ناموں کا زیادہ استعمال جب قسم کا سیاق و سباق ناقص ہو۔
// Problematic: the shorthand obscures which type fromJSON belongs to
SomeConfig config = .fromJSON(data); // What class is this?
// Better: be explicit when the type name adds real information
SomeConfig config = SomeConfig.fromJSON(data);
.fromJSON(data) یہ تکنیکی طور پر ایک ورکنگ شارٹ ہینڈ ہے اگر: SomeConfig اگرچہ یہ ایک سیاق و سباق کی قسم ہے۔ fromJSON طریقہ کا نام اتنا عام ہے کہ پہلی بار پڑھنے والے کو یہ معلوم نہیں ہوگا کہ متغیر کی قسم کو دیکھے بغیر یہ کس کلاس سے آیا ہے۔ شامل SomeConfig اگر آپ اسے کنسٹرکٹر کال میں واضح طور پر لکھتے ہیں، تو آپ اسے فوراً پڑھ سکتے ہیں۔ تمام درست شارٹ ہینڈز کو بہتر نہیں کیا گیا ہے۔
منی اینڈ ٹو اینڈ مثال
آئیے ایک مکمل، حقیقت پسندانہ خصوصیت بناتے ہیں جو تمام کلیدی سیاق و سباق میں ڈاٹ مخففات دکھاتا ہے: شماریات، جامد طریقے، نام کنسٹرکٹرز، سوئچ اسٹیٹمنٹس، اور فلٹر ویجیٹ پیرامیٹرز۔
یہ فیچر ان ایپس کے لیے نیٹ ورک اسٹیٹس انڈیکیٹر ویجیٹ ہے جو کنکشن اسٹیٹس کے لحاظ سے مختلف UI اسٹیٹس دکھاتا ہے۔
شماریات اور ریاستی ماڈل
// lib/models/connection_state.dart
enum ConnectionState {
connecting,
connected,
disconnected,
limited,
error;
bool get isActive => this == .connected || this == .limited;
bool get isTerminal => this == .disconnected || this == .error;
static ConnectionState fromCode(int code) {
return switch (code) {
0 => .connecting,
1 => .connected,
2 => .limited,
3 => .disconnected,
_ => .error,
};
}
String get label => switch (this) {
.connecting => 'Connecting...',
.connected => 'Connected',
.disconnected => 'Disconnected',
.limited => 'Limited Connection',
.error => 'Connection Error',
};
}
bool get isActive => this == .connected || this == .limited استعمال کریں == خصوصی قوانین۔ this ہے ConnectionState مثال کے طور پر، تو this == .connected حل .connected پسند ConnectionState.connected بائیں طرف جامد قسم میں this.
static ConnectionState fromCode(int code) یہ گنتی کا ایک جامد فیکٹری طریقہ ہے۔ ایک سوئچ ایکسپریشن کے اندر واپسی کی قسم ConnectionState ہر ایک کے لیے سیاق و سباق فراہم کرتا ہے۔ => نتیجہ .connecting فیصلہ کریں ConnectionState.connecting, .connected کو ConnectionState.connectedوغیرہ
کہ _ وائلڈ کارڈ کیس واپس کریں۔ .errorیہ بھی اس سے حل ہوتا ہے: ConnectionState.error. String get label سوئچ ایکسپریشنز کا استعمال کریں۔ thisیہ درج ذیل ہے: ConnectionStateکیس کے نمونوں کے لیے سیاق و سباق فراہم کرتا ہے۔ ہر ایک .connecting, .connected, .disconnected, .limitedاور .error یہ متعلقہ گنتی کی قدر کو حل کرتا ہے۔
ترتیب ماڈل
// lib/models/network_config.dart
class NetworkConfig {
final Duration timeout;
final int maxRetries;
final bool showDetailedErrors;
const NetworkConfig({
required this.timeout,
required this.maxRetries,
required this.showDetailedErrors,
});
factory NetworkConfig.standard() {
return NetworkConfig(
timeout: .zero, // Duration context -> Duration.zero
maxRetries: .parse('3'), // int context -> int.parse('3')
showDetailedErrors: false,
);
}
factory NetworkConfig.debug() {
return NetworkConfig(
timeout: .fromSeconds(60), // Duration context -> Duration.fromSeconds(60)
maxRetries: .parse('10'), // int context -> int.parse('10')
showDetailedErrors: true,
);
}
}
timeout: .zero فیلڈ کی اعلان کردہ قسم کا استعمال کریں۔ Duration سیاق و سباق کے ساتھ۔ .zero فیصلہ کریں Duration.zero. maxRetries: .parse('3') فیلڈ کی اعلان کردہ قسم کا استعمال کریں۔ int سیاق و سباق کے ساتھ۔ .parse('3') فیصلہ کریں int.parse('3')یہ ہے int. timeout: .fromSeconds(60) فیصلہ کریں Duration.fromSeconds(60)نام کنسٹرکٹر Duration.
یہ ایک سادہ لیکن حقیقت پسندانہ نمونہ ہے۔ اب یہ ایک فیکٹری کنسٹرکٹر ہے جو اس کی قسم کی وضاحت کیے بغیر ایک جامد طریقہ سے مختلف قسم کا سنٹینل لیتا ہے۔
اسٹیٹس ویجیٹ
// lib/widgets/connection_status_widget.dart
import 'package:flutter/material.dart';
import '../models/connection_state.dart';
class ConnectionStatusWidget extends StatelessWidget {
final ConnectionState state;
final VoidCallback? onRetry;
const ConnectionStatusWidget({
super.key,
required this.state,
this.onRetry,
});
@override
Widget build(BuildContext context) {
return AnimatedSwitcher(
duration: .fromMilliseconds(300), // Duration context
child: _buildContent(context),
);
}
Widget _buildContent(BuildContext context) {
return Padding(
padding: .symmetric(horizontal: 16, vertical: 12), // EdgeInsets context
child: Row(
mainAxisAlignment: .spaceBetween, // MainAxisAlignment context
crossAxisAlignment: .center, // CrossAxisAlignment context
children: [
Row(
mainAxisSize: .min, // MainAxisSize context
children: [
_buildIcon(),
const SizedBox(width: 8),
Text(
state.label,
style: TextStyle(
fontWeight: .w500, // FontWeight context
color: _textColor(),
),
),
],
),
if (state == .error && onRetry != null)
TextButton(
onPressed: onRetry,
child: const Text('Retry'),
),
],
),
);
}
Widget _buildIcon() {
final (IconData icon, Color color) = switch (state) {
.connecting => (Icons.sync, Colors.orange),
.connected => (Icons.wifi, Colors.green),
.disconnected => (Icons.wifi_off, Colors.grey),
.limited => (Icons.signal_wifi_4_bar_lock, Colors.amber),
.error => (Icons.error_outline, Colors.red),
};
return Icon(icon, color: color, size: 18);
}
Color _textColor() => switch (state) {
.connected => Colors.green,
.error => Colors.red,
.disconnected => Colors.grey,
_ => Colors.orange,
};
}
duration: .fromMilliseconds(300) فیصلہ کریں Duration.fromMilliseconds(300) کیونکہ AnimatedSwitcher.duration داخل کیا گیا ہے Duration. padding: .symmetric(horizontal: 16, vertical: 12) فیصلہ کریں EdgeInsets.symmetric(...) کیونکہ Padding.padding داخل کیا گیا ہے EdgeInsets. mainAxisAlignment: .spaceBetween فیصلہ کریں MainAxisAlignment.spaceBetween. crossAxisAlignment: .center فیصلہ کریں CrossAxisAlignment.center. mainAxisSize: .min فیصلہ کریں MainAxisSize.min. fontWeight: .w500 فیصلہ کریں FontWeight.w500 کیونکہ TextStyle.fontWeight ہے FontWeight?.
if (state == .error && onRetry != null) مساوات خاص اصول استعمال کرتی ہے۔ state داخل کیا گیا ہے ConnectionStateتو .error فیصلہ کریں ConnectionState.error. اندر سوئچ کریں _buildIcon() پر سوئچ کریں state (ان پٹ ConnectionState)، جو تمام کیس پیٹرن کے لیے سیاق و سباق فراہم کرتا ہے۔
ہر ایک .connecting, .connected, .disconnected, .limitedاور .error یہ متعلقہ گنتی کی قدر کو حل کرتا ہے۔ کہ _textColor() طریقہ کار میں سوئچ بھی ایک ہی ساخت ہے.
سکرین
// lib/screens/network_demo_screen.dart
import 'package:flutter/material.dart';
import '../models/connection_state.dart';
import '../models/network_config.dart';
import '../widgets/connection_status_widget.dart';
class NetworkDemoScreen extends StatefulWidget {
const NetworkDemoScreen({super.key});
@override
State createState() => _NetworkDemoScreenState();
}
class _NetworkDemoScreenState extends State {
ConnectionState _state = .connecting; // enum shorthand on field
NetworkConfig _config = .standard(); // named constructor shorthand
void _simulateConnection() {
setState(() => _state = .connected); // enum shorthand in closure
}
void _simulateError() {
setState(() => _state = .error); // enum shorthand in closure
}
void _simulateDisconnect() {
setState(() => _state = .disconnected); // enum shorthand in closure
}
void _resetToConnecting() {
setState(() {
_state = .connecting; // enum shorthand in block
_config = .debug(); // named constructor shorthand
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Network Status Demo'),
centerTitle: true,
),
body: Column(
mainAxisAlignment: .center, // enum shorthand on parameter
crossAxisAlignment: .stretch,
children: [
ConnectionStatusWidget(
state: _state,
onRetry: _state == .error ? _resetToConnecting : null,
),
const Divider(),
Padding(
padding: .all(16), // named constructor shorthand
child: Column(
mainAxisSize: .min,
children: [
Text(
'Simulate state change:',
style: TextStyle(fontWeight: .bold),
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: .spaceEvenly,
children: [
ElevatedButton(
onPressed: _simulateConnection,
child: const Text('Connect'),
),
ElevatedButton(
onPressed: _simulateDisconnect,
child: const Text('Disconnect'),
),
ElevatedButton(
onPressed: _simulateError,
child: const Text('Error'),
),
],
),
const SizedBox(height: 8),
TextButton(
onPressed: _resetToConnecting,
child: const Text('Reset'),
),
],
),
),
Padding(
padding: .symmetric(horizontal: 16), // named constructor shorthand
child: Card(
child: ListTile(
title: const Text('Config'),
subtitle: Text(
'Timeout: ${_config.timeout.inSeconds}s | '
'Retries: ${_config.maxRetries}',
),
trailing: Switch(
value: _config.showDetailedErrors,
onChanged: null,
),
),
),
),
],
),
);
}
}
ConnectionState _state = .connecting واضح اقسام کے ساتھ فیلڈز کا اعلان کریں۔ ConnectionStateیہ سیاق و سباق فراہم کرتا ہے: .connecting. یہ اس کے سب سے زیادہ مؤثر استعمال میں سے ایک ہے۔ ویجیٹ کی اسٹیٹ کلاس میں اسٹیٹفول فیلڈز کو شروع کرنا اب ایک ہی پڑھا ہوا اظہار ہے۔
NetworkConfig _config = .standard() جامد فیکٹری طریقہ کو کال کرتا ہے۔ NetworkConfig فیلڈ کی اعلان کردہ قسم کو سیاق و سباق کے طور پر استعمال کرتا ہے۔ setState(() => _state = .connected) استعمال کریں .connected لیمبڈا کے اندر _state اس کا پہلے ہی اعلان کیا جا چکا ہے: ConnectionState. کو تفویض کیا گیا۔ _state سیاق و سباق کی قسم فراہم کرتا ہے۔
_state == .error ? _resetToConnecting : null مساوات خاص اصول استعمال کرتی ہے۔ _state ہے ConnectionStateتو .error فیصلہ کریں ConnectionState.error. mainAxisAlignment: .center, crossAxisAlignment: .stretch, mainAxisSize: .min, fontWeight: .bold, mainAxisAlignment: .spaceEvenly سبھی کو متعلقہ پیرامیٹر کی قسم کے لیے چیک کیا جاتا ہے۔ padding: .all(16) اور padding: .symmetric(horizontal: 16) میں حل کریں EdgeInsets زمرہ Padding.padding.
داخلہ پوائنٹ
// lib/main.dart
import 'package:flutter/material.dart';
import 'screens/network_demo_screen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dot Shorthand Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
home: const NetworkDemoScreen(),
);
}
}
یہ معیاری فلٹر انٹری پوائنٹ ہے۔ ڈاٹ شارٹ ہینڈ کی خصوصیت ایپس کے مربوط ہونے کے طریقے کو تبدیل نہیں کرتی ہے۔ اس کوڈبیس میں تمام شارٹ ہینڈز کو کمپائل کے وقت چیک کیا جاتا ہے، بالکل وہی بائنری تیار کرتا ہے جیسے آپ نے مکمل کوڈ لکھا ہو۔ TypeName.member یہ مجموعی طور پر تشکیل پاتا ہے۔
نتیجہ
ڈاٹ شارٹ ہینڈ ایک ڈرامائی لسانی دوبارہ ڈیزائن نہیں ہے۔ یہ زندگی کے معیار کی ایک درست بہتری ہے جو ڈارٹ اور فلٹر کوڈ سے شور کی ایک مخصوص، اچھی طرح سے متعین کیٹیگری کو ہٹاتی ہے: قسم کے ناموں کی تکرار جو مرتب کرنے والا پہلے سے جانتا ہے۔
جہاں بھی آپ کام کرتے ہیں، آپ صاف اور واضح طور پر کام کرتے ہیں، اور نتیجے میں آنے والا کوڈ دہرائے جانے والے سابقوں کے بصری اوور ہیڈ کے بغیر معنی دیتا ہے۔
اس خصوصیت کی کارکردگی متناسب ہے کہ آپ شماریات، جامد فیکٹریاں، نامزد کنسٹرکٹرز، اور سوئچ اسٹیٹمنٹس کا کتنا استعمال کرتے ہیں۔ ایک بار جب آپ فلٹر ویجٹ لکھتے ہیں، تو آپ ان سب کو مسلسل استعمال کرتے رہیں گے۔ اسی لیے فلٹر کمیونٹی کا ڈاٹ شارٹ ہینڈ پر ردعمل اتنا مضبوط اور مثبت رہا ہے۔ یہ ایک ایسا نمونہ ہے جسے Flutter ڈویلپرز ہر روز تخلیق کرتے ہیں، اور آپ جس پہلے ویجیٹ میں ترمیم کرتے ہیں اس سے آپ کو فوری طور پر شور میں کمی نظر آئے گی۔
ذہنی ماڈل جس کو برقرار رکھنا ضروری ہے فنکشن کے مرکز میں واحد اصول ہے۔ ڈاٹ شارٹ ہینڈ صرف اس صورت میں کام کرتا ہے جب مرتب کرنے والا پہلے سے متوقع قسم کو جانتا ہو۔ ایک بار جب وہ اصول واضح ہو جائیں تو فنکشن قابل قیاس ہو جاتا ہے۔
آپ کو فوری طور پر پتہ چل جائے گا کہ آیا شارٹ کٹ کسی مخصوص جگہ پر درست ہے۔ سیاق و سباق کی قسم تلاش کریں۔ شارٹ ہینڈ اس صورت میں کام کرتا ہے جب آپ کے پاس متغیر اعلامیہ، پیرامیٹر کی قسم، واپسی کی قسم، یا مساوات کا موازنہ بائیں جانب سے ہو۔ اگر نہیں (میں var, dynamicیا ایک غیر تبصرہ شدہ اظہار)، ایسا نہیں ہے۔
موجودہ کوڈ بیس کے لیے اپنانے کا راستہ آسان ہے۔ SDK رکاوٹوں کو اپ ڈیٹ کریں۔ pubspec.yaml. چالو prefer-shorthands-with-enums اگر آپ کی ٹیم اسے استعمال کرتی ہے تو DCM کے Lint کے اصول استعمال کریں۔ لنٹرز کو سب سے قیمتی مواقع تلاش کرنے دیں۔ پہلے سوئچ اسٹیٹمنٹس اور ویجیٹ پیرامیٹر کی گنتی کو منتقل کریں۔ یہ وہ جگہ ہے جہاں سیاق و سباق سب سے زیادہ واضح ہے اور بصری فائدہ سب سے زیادہ ہے۔ وہاں سے، ہم نامزد کنسٹرکٹرز اور جامد طریقوں کے ساتھ کام کرتے ہیں، جہاں قسم کے نام دراصل فالتو معلومات شامل کرتے ہیں۔
یہ فیچر اب Dart 3.10، Flutter 3.38، اور DartPad میں دستیاب ہے۔ مکمل فارم کا استعمال کرتے ہوئے لکھا ہوا موجودہ کوڈ بغیر کسی تبدیلی کے مرتب ہوتا رہے گا۔ گود لینا مکمل طور پر بتدریج ہے۔ ہجرت کی کوئی آخری تاریخ نہیں ہے، کوئی فرسودگی کی وارننگ نہیں ہے، اور طرز عمل میں کوئی فرق نہیں ہے۔ کوڈ پہلے سے ہی کیا کہہ رہا ہے اس کے اظہار کا یہ صرف ایک صاف ستھرا طریقہ ہے۔
حوالہ جات
-
ڈارٹ ڈاٹ شارٹ ہینڈ زبان کا حوالہ: مکمل نحو، تمام درست استعمال کے معاملات،
==اور!=خصوصی قواعد، منسوخ ہونے والی اقسام، اورFutureOr. اس ہینڈ بک میں موجود تمام مواد کے لیے مستند حوالہ۔
https://dart.dev/language/dot-shorthands -
ڈارٹ 3.10 جاری کیا گیا: ڈارٹ 3.10 اور ڈاٹ شارٹ ہینڈ فیچر کا اعلان کرنے والی آفیشل ڈارٹ بلاگ پوسٹ۔ حوصلہ افزائی، سرخی کی مثالیں، اور مکمل مضمون کے لنکس شامل ہیں۔
https://blog.dart.dev/announce-dart-3-10-ea8b952b6088 -
ڈارٹ زبان کا ارتقاء: ایک مکمل ڈارٹ لینگویج ورژن کی تاریخ، جس میں ورژن کے ذریعے متعارف کرائی گئی تمام خصوصیات کی فہرست ہے۔ یہ اس بات کا تعین کرنے کے لیے مفید ہے کہ فیچر کو کس زبان کے ورژن کی ضرورت ہے۔ https://dart.dev/resources/language/evolution
-
ڈاٹ شارٹ ہینڈ فنکشن کی وضاحتیں: ڈارٹ لینگویج گٹ ہب ریپوزٹری میں ڈاٹ شارٹ ہینڈ کے لیے سرکاری زبان کی تفصیلات۔ اس میں نحو کی تبدیلیاں، قسم کے قیاس کے اصول، اور ہر ڈیزائن کے فیصلے کی وجوہات شامل ہیں۔
FutureOrہینڈلنگ ڈیپارٹمنٹ==خصوصی قوانین۔
https://github.com/dart-lang/language/blob/main/accepted/3.10/dot-shorthands/feature-specation.md