Dart Const (const variables)

Flutter Challenge(چالش فلاتر)

توی این قسمت وارد دنیای const میشیم و توضیحات اولیه در مورد نحوه ی برخورد کامپایلر دارت با این اعجوبه میدیم و در نهایت هم const variables رو معرفی میکینم. از اینجا میتونی بخش معرفی این مجموعه مقاله رو مطالعه کنی.

ابتدا بخشی از توضیحاتی رو که توی بخش معرفی از داکیومنت اوردیم رو با هم مرور میکنیم.

If you never intend to change a variable, use final or const, either instead of var or in addition to a type. A final variable can be set only once; a const variable is a compile-time constant. (Const variables are implicitly final.) A final top-level or class variable is initialized the first time it’s used.
اگر هرگز قصد ندارید که یک متغیر رو تغییر بدید به جای استفاده از کلمه کلیدی var از final یا const برای تعریف اون استفاده کنید(یا علاوه بر مشخص کردن نوع متغیر از این کلید واژه ها استفاده کنید).متغیر هایی که به صورت final تعریف شده اند فقط یک بار میتوانند تنظیم شوند(مقدار بگیرند) و قابل تغییر نیستند. متغیرهایی که به صورت const تعریف شده اند ثابت های زمان کامپایل هستند.(توی پرانتز هم میگه که متغیرهای const به صورت ضمنی final هستند.)

بعد از این تعریف چندتا مثال میاره...

final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';
name = 'Alice'; // Error: a final variable can only be set once.

یک متغیر رو final گرفته و بعد خواسته مقدارش رو تغییر بده که به ارور خورده.

در ادامه توضیحاتش این رو اضافه میکنه:

Use const for variables that you want to be compile-time constants. Where you declare the variable, set the value to a compile-time constant such as a number or string literal, a const variable, or the result of an arithmetic operation on constant numbers:
از const برای متغیرهایی استفاده کنید که می خواهید ثابت زمان کامپایل باشند.وقتی یک متغیر const تعریف میکنید و میخواهید به اون مقدار بدید مقدارش رو برابر با یک ثابت زمان کامپایل (compile-time constant) قرار بدید مانند یک رشته یا عدد (string or number literal) یا ....

بعدش هم این مثال ها رو اورده :

const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere

?توی اولین پاراگراف دوتا کلید واژه final و const رو معرفی کرده و گفته از اینها برای تعریف متغیرهایی استفاده کن که قراره ثابت باشن و تغییر نکنن. مخاطب وقتی این رو میخونه میگه آیا توسعه دهندگان دارت دیوونه بودن؟??? چرا دو تا کلید واژه برای یک هدف؟???

?ولی خب در ادامه از یک واژه کلیدی و مهم رونمایی میکنه به اسم Compile-time.بله میگه const در واقع یک compile-time constant یا ثابت زمان کامپایل هست. پس در مقابلش final یک run-time constant یا ثابت زمان اجرا هست.

? پس دو تا سوال توی ذهنمون شکل میگیره که باید بهش جواب بدیم!!!

  • What is compile-time?
  • What is run-time?

شما ادیتور رو باز میکیند و شرو میکنید به کد نوشتن بعد از اون که کدتون تکمیل شد یه build از اپتون یا کدتون میگیرید و بعد خروجی رو توی گوشی یا هر دیوایس دیگه اجرا میکنید.

موقعی که دارید از کدتون build میگیرید کدهای شما یه پروسه ای رو طی میکنند که به اون میگن کامپایل شدن (که وارد جزییاتش نمیشیم) . پس این زمان ینی زمان build گرفتن و ساختن خروجی از کدها برای اجرا روی دیوایس میشه زمان کامپایل یا compile-time.

خیلی ساده بخوایم بگیم توی این زمان کامپایلر دارت میاد شرو میکنه به انالیز و تجیزه کد ها و تبدیل اون ها به کد ماشین و ... که کاری نداریم(فقط بدونیم این تایم compile-time هست کافیه).

و بعد از اون وقتی که خروجی نهایی رو توی دیوایس اجرا میکنید اون زمان میشه run-time.

پس یه نتیجه ای میگیریم اونم این که compile-time یا زمان کامپایل یه شروعی داره و یک پایانی(شروعش همون لحظه ای هست که اقدام میکنیم برای build گرفتن و پایانش هم لحظه آماده شدن خروجی هست) ولی run-time شروعش از لحظه اجرای اپ هست و پایانش لحظه ای هست که اپ رو میبندیم.(خب اینم که یه شروع و پایان داشت پس ولیش کجا بود / عجب جمله چرتی گفتم).

نکته اینجاست که یه اپ یکبار کامپایل میشه ولی بارها و بارها میره توی run-time . ینی به ازای یک compile چند بار run-time رو تجربه میکنه.

و نکته بعدی اینکه وقتی کدهامون کامپایل میشن تمام کدها تجزیه و تحلیل میشن و از زیر تیغ کامپایلر دارت میگذرن ولی موقع اجرا ممکنه بعضی از کدهامون اصلن اجرا نشن.

مثلن یه اپ فلاتر داری که 4 تا صفحه داره که روی هم navigate میشن. وفتی کامپایل میشه همه این صفحات و کدها از زیر تیغ کامپایلر میگذرن ولی موقع اجرا ممکنه شما صفحه اول رو باز کنی و بعد کلن اپ رو ببندی بری پی کارت پس کدهای صفحات دیگ اصلن به حالت اجرایی در نمیان.

حالا که معنی compile-time و run-time رو فهمیدیم برگردیم به تعریف.

میگه const ها ثابت های زمان کامپایل هستن و final ها ثابت های زمان اجرا.

در اینکه هر دو ثابتن و بعد از یکبار تعریف دیگ قابل تغییر نیستن که مشکلی نیست.

??? کد ساده بالا رو ببینید و با توجه به توضیحاتی که تا اینجا گفتیم فکر کنید و بگید تفاوت این دو تا چیه؟

اول فکر کنید بعد جواب رو بخونید.

اولی final تعریف شده پس یک ثابت هست و غیر قابل تغییر و دومی هم const و اون هم ثابت هست.

???تفاوت اینجا هست که کامپایلر دارت توجه ویژه ای به متغیرهایی داره که به صورت const تعریف شده اند.و متغیری که const هست زمان کامپایل توسط کامپایلر تجزیه و تحلیل میشه و توسط چشمان تیزبین کامپایلر مورد رصد قرار میگیره و همون موقع یعنی زمان کامپایل مقدار میگیره, ولی اونی که final هست توی زمان کامپایل مقدار نمیگیره و توی run-time وقتی اجرای کد به اون جا رسید و اون کد اجرایی شد مقدار میگیره.

پس وقتی که یه متغیری const تعریف شد همون زمان کامپایل تکلیفش مشخص میشه (ینی کامپایلر کامل اون رو ارزیابی میکنه و مقدارش هم ثبت میشه) ولی وقتی که متغیر رو final تعریف میکنیم هنگامی که زمان اجرای کد , اجرای کدمون به اون قسمت رسید اون متغیر مقدار میگیره.

❓خب سوال پیش میاد که این تفاوت حالا به چه دردمون میخوره؟ چه دردی رو ازمون دوا میکنه؟

این سوال توی ذهنتون باشه بعدن بهش جواب میدیم.

حالا بریم سراغ جمله کلیدی دیگه از تعاریف:

Where you declare the variable, set the value to a compile-time constant such as a number or string literal, a const variable, or the result of an arithmetic operation on constant numbers:
وقتی یا جایی که یک متغیر const تعریف میکنید و میخواهید به اون مقدار بدید مقدارش رو برابر با یک ثابت زمان کامپایل (compile-time constant) قرار بدید مانند یک رشته یا عدد (string or number literal) یا ....

این چی میگه؟

این میگه که وقتی که یک متغیر رو const تعریف کردی

const constVar = ....

اون مقداری که جای ... و به عنوان مقدار (value) این متغیر قرار میدی مهمه و نمیتونی هر چیزی دلت خواست بذاری.

❓پس چه مقادیری میتونیم بهش بدیم؟

خود مقداره هم باید یه compile-time constant یا ثابت زمان کامپایل باشه و این خاصیت رو داشته باشه که در زمان کامپایل توسط کامپایلر رصد بشه.

خب چرا؟

وقتی که یک متغیر رو مثل کد بالا به صورت const تعریف میکنیم , توی زمان کامپایل کل کد یعنی هم طرف چپ تساوی و هم طرف راست توسط کامپایلر رصد و تجزیه میشه. پس طرف راست (value) هم که قراره بریزمیش توی متغیرمون باید یه خاصیتی داشته باشه ک در زمان کامپایل توسط کامپایلر قابل رصد باشه , پس اونم باید یک compile-time constant باشه.


حالا به دو تا مثال توجه کنید:

کد بالا غلطه و ارور دریافت میکنید.

چون که متغیر final که زمان اجرا مقدار میگیره رو ریختیم توی یه متغیر const که قراره زمان کامپایل مقدار بگیره.(زمان اجرا بعد از زمان کامپایل هست پس کد بالا غلطه)

ولی برعکسش:

کاملن درسته.

چون که داریم متغیری رو که زمان کامپایل مقدار میگیره رو میریزیم داخل متغیری که زمان اجرا قراره مقدار دهی بشه(زمان کامپایل بر زمان اجرا مقدم تره پس کد بالا درسته).


یه نتیجه دیگه میشه از این گفته هامون تا اینجا گرفت. اگه گفتید.

تمام string literal ها و numeric literal ها و ... مثل hello , 2 , true , ... از نوع compile-time constant هستن.

چرا؟

واضحه , تمام کد های زیر درسته و برامون مثل بدیهیات هست:

از طرفی هم گفتیم چون که یک متغیر const زمان کامپایل تجزیه و مقداردهی میشه پس طرف راست تساوی هم باید زمان کامپایل قابل ارزیابی باشه.

پس hello world!!! , 3.14 , false هز سه compile-time constants هستن.


پس تا اینجا یه جمع بندی از نکاتی که گفتیم داشته باشیم.

  • متغیرهایی که به صورت const تعریف میشن compile-time constant هستن و final ها run-time هستن.
  • منظور از compile-time زمانی هستش که کدهامون داره build میشه و منظور از run-time زمانی هست که کد ها داره توی دیوایس اجرا میشه.
  • وقتی که یه متغیری const تعریف میشه کل معادله (طرف چپ و راست ) در زمان کامپایل توسط چشمان تیزبین کامپایلر رصد میشه.
  • وقتی یک متغیری رو به صورت const تعریف میکنیم , مقدار یا value ای هم که قراره داخلش بریزیم باید یک compile-time constant باشه.
  • تمام string literal ها , numeric literal ها , ... compile-time constants هستن و زمان کامپایل توسط کامپایلر رصد میشن.


قسمت بعدی : بررسی مفهوم const در کلاس (static const).

برای دریافت آموزش های بیشتر و شرکت در چالش های فلاتری, کانال فلاتری Flutter Challenge(چالش فلاتر)رو دنبال کن.