نماد سایت برنامه چی | Barnamechi

آموزش دیتا تایپ ها در برنامه نویسی

آموزش دیتا تایپ ها در برنامه نویسی

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

همانطور که در مقاله معرفی متغیر ها توضیح دادیم، وقتی که میخواهیم از داده ها در برنامه خودمان استفاده کنیم، باید مقادیر را در متغیر ها نگهداری کنیم. هر متغیر هم نوع داده ای مخصوص خودش را دارد (البته این موضوع به زبانی که دارین با اون برنامه نویسی میکنین هم بستگی داره). نوع این متغیر ها با استفاده از دیتا تایپ ها مشخص میشود. بعد از اینکه دیتا تایپ را برای متغیر انتخاب کنیم، تازه مشخص میشود که کدام عملگر ها را میتوانیم برای این نوع داده ها استفاده کنیم که هیچ خطایی رخ ندهد.

تعریف Data Type به زبان ساده

اگر بخواهیم به زبان ساده Data Type ها را بررسی کنیم باید بگوییم دیتا تایپ ها یک سری اطلاعات اضافه هستند که همراه با متغیر ها ذخیره میشوند و وظیفه آنها این است که به زبان برنامه نویسی بگویند داده های هر متغیر از چه نوعی است. زبان برنامه نویسی با داشتن این اطلاعات درباره متغیر های ما، میتواند محدودیت هایی روی عملگر ها و پردازش های آینده هر متغیر اعمال کند که از به وجود آمدن Error در زمان اجرا، جلوگیری کند.

دیتا تایپ هایی که معمولا در اکثر زبان های برنامه نویسی استفاده میشوند رشته (string) یا عدد (number یا integer یا float) و غیره هستند که در ادامه مقاله میخواهیم دیتا تایپ های پر استفاده را با هم بررسی کنیم.

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

Type Checking

به روند بررسی و اعمال محدودیت روی دیتا تایپ های استفاده شده در کد، Type Checking گفته میشود. این روند میتواند در زمان کامپایل (که به آن Static Check میگوییم) یا در زمان اجرا (که به آن Dynamic Check میگوییم) اتفاق بیفتد.

از طرفی اگر زبانی نیاز داشته باشد که قوانین تعریف دیتا تایپ درون آن کاملا محکم رعایت شود (یعنی تا جایی که باعث از دست رفتن داده ها نشه اجازه بده دیتا تایپ ها اتوماتیک تغییر کنن ولی اگر خلاف این بود ارور تولید کنه)، در دسته زبان های Strongly Typed قرار میگیرد و اگر غیر از این بود، به آن زبان Weakly Typed گفته میشود.

وجود سیستم Type Checking برای کامپایل شدن و اجرای درست نرم افزار های ما ضروری است. همچنین اگر همه داده ها در متغیر های مناسب ذخیره شده باشند، بقیه عملگر ها و پردازش هایی که روی این داده ها انجام دادیم بدون ارور اجرا خواهند شد. چک کردن این موارد معمولا یا در زمان کامپایل شدن، یا در زمان اجرای نرم افزار اتفاق می افتد و در اکثر زبان های برنامه نویسی از این دو مدل استفاده میشود:

حالا میخواهیم بررسی نزدیک تری از این مدل ها داشته باشیم:

زبان های Statically Typed

در زبان های برنامه نویسی Statically Typed چک کردن همه دیتا تایپ ها در زمان کامپایل نرم افزار اتفاق می افتد (یادتون باشه زمان چک کردن دیتا تایپ ها برای دسته بندی زبان های برنامه نویسی مهمه). وقتی گفته میشود که یک زبان برنامه نویسی Statically Typed است یعنی همه متغیر های آن قبل از اینکه استفاده شوند باید تعریف شده و دیتا تایپ آنها مشخص باشد. اگر این قاعده را رعایت نکرده باشیم قبل از اجرا، یعنی در زمان کامپایل شدن، ارور تولید میشود و نرم افزار به مرحله اجرا نمیرسد.

در زمان کامپایل شدن، همه کدهایی که نوشته ایم به زبانی که برای سیستم قابل فهم باشد ترجمه میشود. یعنی در زبان هایی که Statically Typed هستند باید قبل از شروع به کار کامپایلر، دیتا تایپ همه متغیر هایی که استفاده کردیم را مشخص کرده باشیم.

استفاده از این روند در زبان باعث میشود که همه متغیر ها در دسترس کامپایلر باشند و قبل از اجرای برنامه میتوانیم همه ارور های مربوط به استفاده نادرست از دیتا تایپ ها را بررسی و حل کنیم. زبان های مانند جاوا، سی، سی پلاس پلاس، Scala، Kotlin، Fortran، Go، Pascal و Swift از این دسته هستند.

ویژگی ها

در اکثر این زبان ها برنامه نویس باید وقتی که متغیر را تعریف میکند، دیتا تایپ مناسب داده را هم برای آن تعریف کند. (البته بعضی از زبان های این دسته نیازی به این کار ندارن و خودشون با توجه به نوع داده ای که توی متغیر میریزیم، بصورت خودکار دیتا تایپ رو هم برای اون متغیر تعیین میکنن.)

یکی ویژگی دیگر این دسته از زبان های برنامه نویسی این است که اگر در تعیین دیتا تایپ برای متغیر ها اروری وجود داشته باشد، روند کامپایل کردن نرم افزار متوقف میشود و تا زمانی که مشکل دیتا تایپ را رفع نکنیم نرم افزار کامپایل نمیشود. به عنوان مثال به متغیر های زیر نگاه کنید. میخواهیم دو متغیر به نام های A و B داشته باشیم که دیتا تایپ یکی integer (عدد) و دیگری string (متن) است.

Integer A = ‘hello’
String B = ‘cat’

در این مثال، خط اول یک ارور تولید میکند، چون میخواهیم یک مقدار متنی را درون متغیری با دیتا تایپ integer بریزیم که مخصوص داده های عددی است. اما خط دوم مشکلی ندارد چون متن را درون متغیری که دیتا تایپ مناسب این داده را دارد ذخیره کردیم.

علاوه بر این موارد، وقتی که متغیر را با یک دیتا تایپ مشخص تعریف میکنیم، نمیتوانیم بعدا دیتا تایپ این متغیر را تغییر بدهیم. یعنی در مثال بالا نمیتوانیم مقدار های عددی را در متغیر B ذخیره کنیم.

زبان های Dynamically Typed

وقتی یک زبان Dynamically Typed باشد با مقادیر Run-time، متغیر ها و فیلد های بدون نام و غیره سر و کار خواهد داشت. این مقادیر میتوانند در زمان اجرا تغییر کنند و قبل از کامپایل شدن در دسترس کامپایلر نیستند که خطای آنها را قبل از اجرا بتوانیم رفع کنیم. وقتی برنامه نویس ها با این دسته از زبان های برنامه نویسی کار میکنند، معمولا سریعتر میتوانند روند کدنویسی را جلو ببرند، زیرا نیاز نیست قبل از استفاده از همه متغیر ها، آن ها را تعریف کرده باشیم.
زبان هایی مانند Perl، Ruby، Python، PHP، Javascript و Erlang در این دسته قرار میگیرند.

ویژگی ها

برای این دسته از زبان های برنامه نویسی، نیازی نیست وقتی متغیر ها را تعریف میکنیم، دیتا تایپ آنها را هم به صورت صریح مشخص کنیم. خود زبان برنامه نویسی دیتا تایپ متغیر ها را در زمان اجرا تشخیص میدهد. برای مثال تعریف متغیر در این زبان ها میتواند به این شکل باشد:

Varc = 52

در این مثال میبینید که مقدار 52 را درون متغیر varC ریختیم و نیازی نیست که مانند مثال قبلی نوع داده این متغیر را تعریف کنیم اما به جای آن میتوانیم دیتا تایپ متغیر را بعدا تغییر بدهیم.

به عنوان مثال اگر بخواهیم نوع متغیر varC را از عدد به string تغییر بدهیم، هیچ اروری ایجاد نخواهد شد. با این انعطاف در تغییر نوع داده ها، برنامه نویس میتواند نرم افزار خودش را با انعطاف بیشتری برنامه نویسی کند. اما در عوض زمان اجرای نرم افزار بیشتر میشود، چون همه دیتا تایپ ها باید در زمان اجرا بررسی شده و مشخص شوند.

بیشتر زبان های اسکریپت نویسی نیز از این نوع زبان ها هستند، زیرا کامپایلری در آنها وجود ندارد که بررسی دیتا تایپ ها را در نرم افزار انجام بدهد. اما مشکلی که در اینجا وجود دارد فرآیند دیباگ کردن نرم افزار است که گاهی سخت تر از زبان های Statically Typed است. چون همه چیز را باید در زمان اجرا رهگیری و اشکال زدایی کنید.

زبان های Strongly Typed

زبان های Strongly Typed زبان هایی هستند که در آن ها باید برای متغیر ها دیتا تایپ های مخصوص خودشان را تعریف کنیم و اگر داده هایی که درون این متغیر ها میریزیم با نوع داده آنها همخوانی نداشته باشد، ارور ایجاد خواهد شد و مهم نیست که چک کردن دیتا تایپ ها در چه زمانی اتفاق خواهد افتاد.

پایتون و جاوا زبان های Strongly Typed هستند.

زبان های Weakly Typed

زبان های Weakly Typed زبان هایی هستند که متغیر ها به دیتا تایپ خاصی نسبت داده نمیشوند، با این حال دیتا تایپ مخصوص خودشان را دارند، اما قید و بندی های کمتری در زمان چک کردن نوع داده ها در آن ها وجود دارد.

PHP یکی از زبان های Weakly Typed است.

مثال PHP

$temp = “Hello World!”;
$temp = $temp + 10; // no error caused
echo $temp;

در مثال بالا متغیر temp را تعریف کردیم و یک مقدار String درون آن ریخته ایم. اما در خط دوم مقدار متغیر را با 10 جمع کردیم که یک مقدار عددی است. در این حالت زبان PHP هیچ اروری تولید نمیکند و اجازه این کار را به ما میدهد. همه زبان های Weakly Typed به این شکل عمل میکنند.

انواع دیتا تایپ ها

دیتا تایپ ها میتوانند بر اساس زبان برنامه نویسی یا پلتفرمی که از آن استفاده میکنید تغییر کنند. اما در این قسمت میخواهیم یک دسته بندی کلی از دیتا تایپ های مختلف ارائه بدهیم و پر استفاده ترین آنها را معرفی کنیم. دیتا تایپ ها به دو دسته کلی تقسیم میشوند:

دیتا تایپ های اولیه (Primitive Data Types)

دیتا تایپ های اولیه معمولا تایپ هایی هستند که به صورت پیشفرض یا پیش ساخته درون زبان برنامه نویسی پیاده سازی شده اند و اسم آن ها با استفاده از یک کلمه کلیدی درون زبان رزرو شده است (یعنی شما نمیتونین یه دیتا تایپ بسازین که هم اسم یکی از دیتا تایپ های Primitive باشه. در مورد ساختن دیتا تایپ هم توی تاپیک های بعدی صحبت میکنیم). تعدادی از دیتا تایپ های Primitive این ها هستند:

در بعضی موارد ممکن است طوری به نظر برسد که انگار میتوانیم مستقیما روی این نوع داده ها یک متد را صدا بزنیم. مثلا میتوانیم روی یک متغیر که مقدار رشته ای دارد این کار را انجام بدهیم:

"foo".includes("f")

و یک خروجی از نوع boolean بگیریم که در اینجا مقدار true به ما برگردانده میشود. اما در تعریف دیتا تایپ های اولیه گفتیم که این دیتا تایپ ها آبجکت هیچ کلاسی نیستند و بنابراین متدی را نباید بتوانیم روی آن صدا بزنیم. اتفاقی که در اینجا رخ میدهد این است که وقتی این متد ها روی متغیر های Primitive صدا زده میشوند، زبان برنامه نویسی به صورت اتوماتیک یک آبجکت Wrapper از کلاس مخصوص خودشان درست میکند (توی این مثال کلاس String رو استفاده میکنه و دقت کنین کلاس String با حرف بزرگ شروع میشه و با دیتا تایپ string فرق داره) و متدی که صدا میزنیم از آن کلاس خوانده میشود (یعنی اینجا متد String.prototype.includes() صدا زده شده).

برای اینکه بدونین چه متد هایی رو میتونین روی دیتا تایپ های اولیه صدا بزنین، توی دوره آموزش جاوا اون قسمت هایی که مربوط به کلاس ها هستن رو بخونین، مثلا کلاس String یا کلاس Integer.

به زبان پیشرفته تر، دیتا تایپ های Primitive یک آبجکت نیستند و هیچگونه متد (Method) یا ویژگی (Property) دیگری ندارند. در حقیقت همه متغیر هایی که با استفاده از دیتا تایپ های Primitive میسازیم، Immutable هستند. یعنی بعد از تعریف کردن آنها، نمیتوانیم مقدارشان را تغییر بدهیم. البته شاید این حرف از نظر شما درست نباشد و متغیر هایی از این نوع داشته باشید که چندین بار در طول نرم افزار مقدار آنها تغییر میکند.

با یک مثال این مسئله را بررسی میکنیم. فرض کنید یک متغیر از نوع عدد تعریف کردیم که اسم آن x و مقدار اولیه آن 5 است. سپس یک عملیات مثل x=x+3 را روی آن انجام میدهیم. شاید این طور به نظر برسد که مقدار x به 8 تغییر کرده. اما اتفاقی که در واقعیت رخ میدهد این است که یک مقدار جدید 8 از نوع عدد تولید میشود و متغیر x به این مقدار جدید نسبت داده میشود. مقدار اصلی 5 دست نخورده باقی خواهد ماند.

ویژگی Immutable بودن دیتا تایپ های اولیه به آنها این اجازه را میدهد که Thread-Safe باشند. یعنی از آنجایی که نمیشود این داده ها را تغییر داد، میتوانیم آنها را بدون استفاده از مکانیزم های Synchronization روی نخ (Thread) های مختلف نرم افزار استفاده کنیم. برای مطالعه بیشتر درباره Thread ها پیشنهاد میکنم این مقاله را مطالعه کنید:

همچنین Immutable بودن داده های اولیه میتواند به بهینه سازی نرم افزار ما کمک کند. یعنی در بعضی موارد کامپایلر یا مفسر میتواند این مقدار ها را مستقیما روی حافظه رم ذخیره کند و بنابراین دسترسی و خواندن آنها با سرعت بیشتری اتفاق می افتد.

دیتا تایپ های ترکیبی (Composite Data Types)

دیتا تایپ های ترکیبی که به آنها Compound Data Types یا Aggregate Data Types هم گفته میشود، مواردی هستند که از ترکیب انواع ساده تر دیتا تایپ ها به وجود می آیند و به شما اجازه میدهند داده های مرتبط با هم را در یک گروه جمع آوری کنید ولی با آنها مثل یک داده واحد رفتار کنید.

دیتا تایپ های ترکیبی میتوانند قدرت دسته بندی و استفاده از داده ها به صورت مرتب و ساختار یافته را به ما بدهند و مدیریت مجموعه داده ها را برای ما آسان تر کنند.

تعدادی از دیتا تایپ های Composite که بیشتر استفاده میشوند را با هم بررسی میکنیم:

numbers = [1, 2, 3, 4, 5]
struct Person {
    char name[20];
    int age;
};

struct Person john;
john.name = "John";
john.age = 25;
}
class Rectangle {
    int width;
    int height;

    int calculateArea() {
        return width * height;
    }
}

Rectangle rect = new Rectangle();
rect.width = 10;
rect.height = 5;
}

record Person(String name, int age) {}
Person john = new Person("John", 25);
car = ("Toyota", "Camry", 2019, "Blue")

دیتا تایپ های انتزاعی (Abstract Data Types)

دیتا تایپ های انتزاعی که به صورت مخفف با اسم ADT شناخته میشوند، یک مفهوم در برنامه نویسی هستند که یک نگاه سطح بالا از داده ها و عمل هایی که میتواند روی آنها انجام شود را توضیح میدهند. یعنی تمرکز ADT ها روی رفتار و عملکرد ساختار های داده ای است، نه جزئیات پیاده سازی آنها.

ADT ها به ما این توانایی را میدهند که داده ها و عملیات ها را توی یک واحد بسته بندی کنیم که به برنامه نویس ها این اجازه را میدهند که با مفاهیم انتزاعی به راحتی کار کنند و نگران کارهای داخلی آنها نباشند. پیاده سازی دقیق ADT ها میتواند بسته به زبان برنامه نویسی یا Context مورد استفاده تغییر کند (یعنی علاوه بر زبان، جایی که داریم از این ها استفاده میکنیم هم میتونه نحوه پیاده سازی رو تغییر بده).

هرجا صحبت از انتزاع یا Abstract شد، بدونین که با پیاده سازی و جزئیات کاری نداریم. وقتی داریم با انتزاع سر و کله میزنیم یعنی داریم قوانین و قواعد کلی رو تعریف میکنیم. مثل قوانین رانندگی که کاری ندارن ماشین چه برند، رنگ یا مشخصاتی داره. قانون رو همه ماشین ها باید رعایت کنن.
ADT ها توی برنامه نویسی هم همین طور هستن. قاعده ی اینکه چه داده هایی باید استفاده بشه و چجوری میتونیم این داده ها رو بخونیم و حذف کنیم و تغییر بدیم رو اینجا مشخص میکنیم، دیگه کاری نداریم که کجا قراره چه داده ای توش ریخته بشه. فقط هرجا بعدا از ADT ها استفاده کردیم، باید این قانون ها رو رعایت کنیم و بدونیم این مجموعه داده های ما از قوانین ADT داره پیروی میکنه.

ADT ها شامل دو کامپوننت (بخش) اصلی هستند:

  1. داده ها (Data): بخش داده ها در ADT نمایانگر داده ها یا المان هایی هستند که میتوانیم درون آن ذخیره کنیم. این داده ها میتوانند از هر دیتا تایپی باشند، از انواع اولیه گرفته تا بقیه ساختار های داده پیچیده تری که در مورد آنها صحبت کردیم.
  2. عملیات ها (Operations): بخش عملیات، همه اعمالی که میتوانیم روی داده های موجود در ADT انجام دهیم را تعریف میکند. این Operation ها میتوانند شامل افزودن یا حذف کرده یک المان، خواندن یا ویرایش داده ها، جستجو در المان ها یا عملیات های مرتبط دیگری باشند.

تعدادی از مثال های مورد استفاده از ADT ها را با هم بررسی میکنیم:

اهمیت دیتا تایپ ها

اگر شما هم درگیر یادگیری دیتا تایپ ها در برنامه نویسی باشید، ممکن است این سوال را داشته باشید که یادگیری این همه دیتا تایپ مختلف به چه دردی میخورد؟ در حالی که میتوانید زمان خود را صرف بهبود بیزینس و کارهای مهمتری بکنید. اما اهمیت یادگیری دیتا تایپ ها به همین جمله خلاصه میشود: برای داشتن یک ساختار داده ای تمیز و مستحکم. اما برای بررسی دقیق تر این مسئله، تیتر های زیر را مطالعه کنید:

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

سوالی دارید؟

توی این مقاله درباره دیتا تایپ ها، انواع اون ها، موارد استفاده شون و اهمیت Data Type ها در برنامه نویسی صحبت کردیم. اگر هر سوالی در این زمینه دارید میتوانید آن را در قسمت نظرات (همین پایین) بنویسید تا به سرعت به آنها پاسخ بدهیم.

منابع

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

خروج از نسخه موبایل