مقدمه ای بر Null Safety در دارت
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 6 دقیقه

مقدمه ای بر Null Safety در دارت

اولین معرفی از ویژگی Null Safety در دارت به عنوان پیش نمایش (tech preview) در اوایل ژوئن سال جاری (2020) انجام شد و دیگری در اواخر اکتبر آمد.

در این مقاله ما ویژگی های زبان دارت و همه چیز مرتبط با Null Safety در دارت - که پایه و اساس چارچوب flutter است - و همچنین نحوه ی استفاده از آن را بررسی می کنیم.

Null Safety در دارت

Null Safety یک ویژگی کاربردی نسبتاً مدرن است که به ما کمک می کند از موارد خاص (exception) تهی (null) در برنامه های خود اجتناب کنیم ، این نوع exception ها مجموعه ای از اشکالات هستند که به راحتی اشکال زدایی (debug) نمی شوند.

Null Safety یک نقطه عطف بزرگ برای زبان دارت است و همچنین باعث بهبود عملکرد می شود و در نسخه 2.9 دارت به عنوان یک ویژگی جدید زبانی معرفی شد.

در نسخه 2.9 دارت، همه ی type ها به طور پیش فرض non-nullable (غیر تهی) هستند و بنابراین مقادیری که می توانند تهی باشند باید مشخص شوند.

متغیرهای nullable متغیرهایی هستند که ممکن است حاوی یک مقدار معتبر باشند یا نباشند - در حالت دوم ، آنها null یا تهی در نظر گرفته می شوند، در حالی که متغیرهای non-nullable یا غیرتهی همیشه باید دارای یک مقدار باشند و هرگز نمی توانند null یا تهی باشند.

void main(){
  String name;
  name = null;
  print("Name is $name");
}

با ویژگی Null Safety دارت ، کدی مانند کد بالا خطا ایجاد می کند و کامپایل نمی شود.

از آنجا که همه ی type ها به طور پیش فرض non-null هستند ، همیشه مهم است که یک متغیر non-null را با مقادیر non-null مقدار دهی کنیم. این به ما کمک می کند کد null-safe را با ضمانت قوی در زمان کامپایل بنویسیم.

اهمیت Null Safety

زبان برنامه نویسی دارت یک زبان type-safe است. این بدان معناست که وقتی متغیری برای مثال یک رشته (string) را تعرفی می کنید ، نمی توان به آن یک int یا هر متغیر نوع دیگری اختصاص داد. برای مثال به قطعه کد زیر نگاه کنید:

void main() {
  String name;
  name= 2;
}

با نگاه کردن به کد بالا آیا می توانید مشکل را تشخیص دهید؟ به متغیر رشته بدیهی است که نمی توان مقدار int اختصاص داد و در نتیجه کامپایلر خطایی را نشان می دهد.

اگرچه این امر برای اجتناب از exception ها عالی است اما این لزوماً تضمین نمی کند که متغیر به خودی خود null نیست و در طول زمان اجرا نیز null نخواهد بود و این می تواند باعث شود که برنامه ما در طول این مدت یک exception ایجاد کند.

یکی از ویژگیهای null safety این است که ما نمی توانیم خطاهای null را در زمان کامپایل به جای زمان اجرا تشخیص دهیم.

بیایید مورد دیگری را برسی کنیم و ببینیم که چگونه null safety کار ما را ساده تر می کند:

List<File> newFile;

void main(){
  printLengths(newFile);
}

void printLengths(List<File> files) {
  for (var file in files) {
    print(file.lengthSync());
  }
}

به نظر می رسد کد بالا بسیار خوب کار می کند ، اما در زمان اجرا یک null exception ایجاد می کند. در حال حاضر هنگام کار کردن با چند خط کد ، این مشکل به راحتی قابل مشاهده است اما در محصول واقعی با چند صد خط کد، می تواند به عنوان یک اشکال جدی مطرح شود که می تواند توسعه دهنده را درگیر کند و زمان توسعه ما را طولانی تر کند.

به همین دلیل است که قابلیت null safety دارت برای بررسی این امر هنگام کد نویسی درست شده. بدون null safety، کدی مانند قطعه فوق کامپایل نمی شود و قطعه کد بالا با ویژگی null safety جدید دارت، خطایی ایجاد می کند.

کار با Nullable ها در دارت

دارت راهی برای تعریف مقادیر nullable ارائه می دهد. این را می توان با افزودن علامت سوال (?) به پارامتر type انجام داد و این به کامپایلر می گوید که این مقدار می تواند null باشد.

void main() {
  String? name;
  name= null;
}

کد بالا خطایی ایجاد نمی کند و همچنین بعداً می توانیم non-value را به نام متغیری اختصاص دهیم و همچنان برای کامپایلر مشکلی ایجاد نمی کند.

void main() {
  String? name;
  name= null;
  name="Mike";
}

تبدیل Type با برسی Null بودن در دارت

گاهی اوقات ما مقادیر nullable را تعریف می کنیم و این مقادیر می توانند برای کامپایلر مشکل ایجاد کنند، اجازه دهید نگاهی به مثال زیر بیندازیم:

void printNameLength(String? name) {
  print(name.length);
}

کد بالا کامپایل نمی شود و این به این دلیل است که در عملیات، قطعا خطایی خواهیم داشت که متغیر ما خالی است.

یکی از راه های حل این مسئله ، انجام یک بررسی null بودن بر متغیر است که مقدار را به یک مقدار non-null تغییر می دهد و سپس می توانیم هر عملیاتی را روی متغیر انجام دهیم.

افزودن این عملیات برسی null بودن به قطعه کد بالا چیزی شبیه به این خواهد بود:

void printNameLength(String? name) {
  if (name == null) {
    return;
  }
  print(name.length);
}

به منظور تبدیل این متغیر ، کامپایلر باید تأیید کند که مقدار خالی نیست و هنگامی که این اتفاق می افتد ، می توان متغیر را به یک مقدار non-nullable تبدیل کرد.

استفاده از مقادیر Non-Nullable با کلاسها

متغیرهای نمونه در کلاسها اگر Non-Nullable باشند باید مقداردهی اولیه شوند ، این بدان معناست که ما می توانیم کدی مانند کلاس اول بنویسیم اما کلاس دومی خطا ایجاد می کند:

class Codesource{
  String name = "My name";
}

class CodeSource{
  String name;
}

یک راه حل برای خطایی که کامپایلر در مورد کلاس دوم ایجاد می کند این است که آن را با constructor کلاس به این شکل تنظیم کنید:

class CodeSource{
  CodeSource(this.name);
  String name;
}

وظیفه قطعی

کامپایلر دارت دقیقاً می داند که متغیرها چه موقع ایجاد، تخصیص و همچنین چه زمانی فراخوانده می شوند.

بیایید نگاهی دقیق به کد زیر بیندازیم:

String name(String name) {
  String value;
  print(value.length());
  if (name.isNotEmpty) {
    value= name;
  } else {
    value = "No name provided";
  }
  print(value);
  return value;
}

در خط 3 کد بالا ، کامپایلر به ما می گوید که خوشحال نیست زیرا ما در حال تلاش برای خواندن از مقداری هستیم که مقداردهی اولیه نشده است و پس از تعیین مقدار در خط 5 ، دفعه بعد که سعی می کنیم آن را بخوانیم هیچ خطایی نمی دهد.

کلید واژه Late

از کلید واژه Late می توان برای نشان دادن متغیرهایی استفاده کرد که بلافاصله هنگام ایجاد مقدار دهی نمی شوند بلکه زمانی مقدار دهی می شوند که فراخوانی می شوند. این بدان معناست که ما می توانیم در کلاس ها، فیلدهای نمونه non-null داشته باشیم که بعداً مقدار دهی می شوند.

class ExampleState extends State {
  late final String name;

  @override
  void initState() {
    super.initState();
    name= 'Mike';
  }
}

نتیجه گیری

با توجه به مثال هایی که برسی کردیم، می توانیم ببینیم که ویژگی جدید زبان دارت یعنی Null Safety بسیار کاربردی است و همینطور در صورت استفاده نادرست، کامپایلر دارت ناراضی خواهد شد.

همیشه به خاطر دارید که از اپراتور آگاه از null استفاده کنید؟ هنگام تعریف type متغیر ها یا پارامتر های نامگذاری شده (named parameters) به منظور کاهش خطاهای زمان کامپایل، دلیل نیاز به استفاده از این ویژگی را درک خواهید کرد.

برای اطلاعات بیشتر می توانید به documentation رسمی در مورد null safety مراجعه کنید.

منبع

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
3 از 2 رای

/@armanabkar
آرمان آبکار
Software Developer

توسعه دهند موبایل (iOS) و فرانت اند

دیدگاه و پرسش

برای ارسال دیدگاه لازم است وارد شده یا ثبت‌نام کنید ورود یا ثبت‌نام

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

آرمان آبکار

Software Developer

مقالات برگزیده

مقالات برگزیده را از این قسمت میتوانید ببینید

مشاهده همه مقالات