آموزش برنامه نویسی سوئیفت (Swift): عملگر، Optional و مقادیر تهی – بخش سوم


در بخش قبلی این سری مطالب آموزش سوئیفت با انواع مقداری، انواع ارجاعی و همچنین انواع مجموعهای آشنا شدیم. در این مقاله نیز به ادامه معرفی مباحث مقدماتی میپردازیم؛ اما خبر خوب این است که پس از پایان این مقاله شما قادر خواهید بود برنامهای بنویسید که مسائل ریاضیاتیتان را حل کند. این مسائل ریاضیاتی میتواند از موارد بسیار ساده تا محاسبات مالی پیچیده را شامل شود.
مقدمه
شما باید با مفهوم تقدم عملیات ریاضی آشنا باشید. البته اگر فکر میکنید در این زمینه معلومات کافی ندارید در ادامه فهرستی از تقدم عملگرها ارائه کردهایم:
- پرانتز (از داخل به خارج)
- توانها از چپ به راست
- ضرب از چپ به راست
- تقسیم از چپ به راست
- جمع از چپ به راست
- تفریق از چپ به راست
عملگرها
اگر شما کلاس سوم ابتدایی را سپری کرده باشید، میبایست با اغلب عملگرهای برنامهنویسی آشنا باشید. در ادامه برخی از عملگرهایی که احتمالاً میشناسید ارائه شدهاند:
1// Math Operators
2// Addition
3var a = 10 + 20 // a is equal to 30 (10 + 20 = 30)
4// Subtraction
5var s = 100 - 75 // s is equal to 25 (100 - 75 = 25)
6// Multiplication - we use * to multiply
7var m = 10 * 15 // m is equal to 150 (10 x 15 = 150)
8// Division - we use / to divide
9var d = 100 / 50 // d is equal to 2 (100 ÷ 50 = 2)
10/*
11 *note about division, it is easy to divide numbers and end up
12 * with a float value (decimal value)
13 * if you do not make the variable strongly typed you will end up
14 * with an an Integer value (6 / 5 = 1)
15 * (e.g. var a: Float = 50 / 100 or var a: Double = 50 /100)
16 */
17// Exponent - we will cover this in the future, promise!
18// Comparison operators
19// Greater than
20var gt = 2 > 1 // gt is equal to true (2 is bigger)
21// Less than
22var lt = 2 < 1 // lt is equal to false (2 is not smaller)
23// Equal to - we use double equal signs to determine equality
24// we use a single equal sign for assignment
25var eq = (2 == 2) // eq is equal to true (2 is equal to 2)
26// Greater than or equal to
27var gtEq = (2 >= 2) // gtEq is equal to true (2 is equal to 2)
28// Less than or equal to
29var ltEq = (2 <= 3) // ltEq is equal to true
30// Unary Operators (1 operand, binary is two operands as above)
31// Not equal
32var notEq = (2 != 3) // notEq is true
33// Minus operator (there is a plus but it does not change anything)
34var minus = -(-100) // minus is 100
35// Logical Operators
36// And operator - this and that must be true
37var andOp = (true && 3 == 3) // andOp equals true
38// Or operator - this or that must be true
39var orOp = (true || false). // orOp equals true
40// Not operator - reverses the result of a boolean evaluation
41var isRaining = !true // isRaining is false
مطمئناً موافق هستید که همه این مفاهیم ساده هستند. بنابراین در ادامه برخی از عملگرهایی را که شاید کمتر آشنا باشید ارائه کردهایم:
1// Remainder - also referred to as Modulo
2var r = 25 % 7 // r is equal to 4 (25 / 7 = 3 with remainder of 4
احتمالاً این عملگر آخر برای شما کمی عجیب باشد؛ اما کاربردهای زیادی دارد. با آن میتوان عملیات مختلف ریاضی برای حل مسائل مختلف اجرا کرد. برای نمونه تصور کنید میخواهیم به هر حرف الفبا یک عدد اختصاص بدهیم و میخواهیم 34-اُمین حرف الفبای فارسی را بدانیم. شاید از خود بپرسید الفبای فارسی که 32 حرف بیشتر ندارد! بله درست است؛ اما اگر پس از پایان حروف دوباره از نو شروع به اختصاص شماره بکنیم متوجه میشویم که 34-اُمین حرف «ب» خواهد بود. این محاسبات با استفاده از عملگر % امکانپذیر است. میتوان کدی به صورت زیر نوشت:
var value = 28% 26. value
که نتیجه برابر با عدد 2 یعنی حرف «ب» خواهد بود. روش رمزگذاری سزار نیز به همین ترتیب عمل میکند و متعاقباً رمزگذاری ویجنر (Vigenère) نیز از روی آن ساخته شده است.
عملگرها کاربرد فراوانی در برنامهنویسی دارند. برنامهها به کمک عملگرها میدانند که باید چه کار بکنند. از عملگر جمع میتوان برای کارهایی به جز جمع کردن اعداد نیز استفاده کرد. برای مثال میتوانیم از آن برای الحاق دو رشته به هم استفاده کنیم.
1var firstName = "John"
2let lastName = "Doe"
3let fullName = firstName + " " + lastName
دقت کنید که ما از نام دو متغیری که تعریف کردهایم استفاده نمودهایم.
1let fullName = "John" + " " + "Doe"
بدین ترتیب میتوانیم از متغیرها و ثابتها برای نگهداری مقدارهای مختلف استفاده کنیم و دیگر نیازی نیست که آنها را مجدداً تایپ کنیم. نکته خوب این است که هر دو متغیر firstName و lastName طولانیتری از مقداری که در خود جای دادهاند، هستند. برای نمونه میتوانیم مثال خود را طوری تغییر دهیم که نام خانوادگی به صورت «Supercalifragilisticexpialidocious» باشد. Xcode قابلیت کامل سازی خودکار دارد که قابلیت بسیار مفیدی محسوب میشود و علاوه بر آن دیگر نیاز نیست همواره بدانیم که مقدار firstName یا lastName چه خواهد بود و کافی است از نام متغیر به جای مقدار آن استفاده کنیم و مطمئن خواهیم بود که صرفنظر از این که نام چیست همواره در متغیر خود نام به علاوه یک فاصله و متعاقباً نام خانوادگی را داریم.
یک روش میانبر برای افزودن، تفریق، ضرب و یا تقسیم کردن این است که عملگر را به عملگر انتساب (=) الحاق کنیم. بدین ترتیب میتوانیم رشتهها را نیز به هم الحاق کنیم.
1var firstNumber = 1
2let secondNumber = 2
3
4firstNumber += secondNumber
5// first number is now equal to 3
6firstNumber *= secondNumber
7// first number is now equal to 6 becuase firstNumber became 3 in
8// the last operation and we just multiplied it by 2
9firstNumber -= secondNumber
10// firstNumber is now 4
11firstNumber /= secondNumber
12firstNumber /= secondNumber
13// that was on purpose because I want you to guess what the value is
14var name = "John"
15var lastName = "Doe"
16var name += (" " + lastName)
17// name is now "John Doe"
تلاش کنید این کدها را امتحان کنید و حتی آنها را دستکاری کنید تا به خوبی با کارکرد هر کدام آشنا شوید.
Optional-ها و مقادیر تهی
تلاش میکنیم این مفاهیم را تا حد امکان به زبان ساده توضیح دهیم. اگر به بخش نخست این سری مطالب آموزش سوئیفت (+) مراجعه کنید، میبینید که در مورد اعلان و وهلهسازی از متغیرها صحبت کردهایم. ما اعلان متغیرها را به اختصار بیان کردیم و به جای آن وهلهسازی از متغیرها را توضیح دادیم. اینک نوبت آن رسیده است که این دو مفهوم را به طور کامل ارائه دهیم.
میتوان یک متغیر را صرفاً اعلان کرد:
1var a: Int
و سپس مقداری را به این متغیر نسبت داد:
1a = 125
این فرایند کاملاً صحیح است؛ اما سؤال این است که پیش از آن که مقداری به متغیر دهیم، متغیر ما چه مقداری داشته است؟
پاسخ این است که متغیر ما مقدار تهی (nil) داشته است. دقت کنید که تهی به معنی صفر نیست؛ بلکه به معنی هیچ، هیچ چیز و پوچ است. برای این که معنی تهی را بهتر درک کنید، پیشنهاد میکنیم کمی بالاتر بروید و تصویر دفترچه یادداشتی که ارائه شده است دقت کنید. این دفترچه 200 برگ دارد و زمانی که همه صفحهها را نوشتیم و تمام کردیم، آنها را جدا میکنیم تا این که به صفحه آخر برسیم و دیگر برگهای در دفترچه نماند. در این حالت دفترچه ما 0 برگه دارد. تنها چیزی که مانده است فنری است که زمانی محتوی 200 برگه کاغذ بوده و احتمالاً جلد دفترچه نیز مانده است. همه اینها روی میز تحریر بر جای ماندهاند. اینک میتوانید تصور کنید که میز تحریر متغیر ما است، فقدان دفترچه به این معنی است که متغیر تهی است. میدانیم که میز دفترچهای را نگهداری میکند که میتواند شامل تعداد صحیحی از اوراق باشد؛ اما برگهای در دفترچه ما نیست و از این رو وهلهسازی نشده است.
بنابراین اگر بخواهیم جمعبندی بکنیم، میز میتواند حاوی دفترچهای باشد که برگههایی دارد، اما فعلاً ما دفترچهای روی میز نداریم و از این رو تهی است. در ادامه با ساختاری که احتمالاً تاکنون ندیدهاید این وضعیت را در کد بررسی میکنیم:
1var name: String?
علامت ? در انتهای نوع متغیر به سوئیفت اعلام میکند که متغیر یک مقدار optional است. شما نمیتوانید متغیر و ثابتهای غیر optional را به صورت تهی داشته باشید. شما حتی میتوانید متغیرهای optional را در زمان اعلان شدن، وهلهسازی کنید:
1var name: String? = "James"
کد فوق به ما میگوید که مقدار متغیر name را برابر با nil قرار میدهیم.
شاید از خود بپرسید که چرا باید مقدار یک متغیر optional را در ابتدا به صورت یک مقدار غیر تهی تعیین کنیم؟ فرض کنید میخواهید نام خانوادگی یک نفر را که در یک پلتفرم شبکه اجتماعی است ارائه کنید. به این منظور میتوانید یک متغیر به نام LastName به صورت optional تعریف کنید و سوئیچی تعبیه کنید که آیا باید این نام نمایش یابد یا نه. اگر سوئیچ روشن باشد، نام خانوادگی فرد را به کاربران دیگر نمایش میدهیم. در حالت خاموش بودن آن سوئیچ، متغیر LaseName را برابر با مقدار تهی تنظیم میکنیم. در ادامه مقدار LaseName را در صورتی که مقداری داشته باشد نمایش میدهیم.
Optional-ها بسیار قدرتمند هستند و باعث شدهاند که زبان برنامه نویسی سوئیفت به زبانی کاملاً امن تبدیل شود. این امنیت از دو جهت تأمین میشود یکی این که optional-ها تضمین میکنند در هر حالتی میتوانید از دسترسی به دادههایی که انتظار نمیرود ممانعت کنید و دوم این که این اطمینان را ارائه میکند که انواع مختلف، به روش صحیحی استفاده میشوند.
Optional-ها و مقادیر تهی همچنان امکان تعیین مقادیر پیشفرض با استفاده از عملگرهای دیگر را فراهم میسازند. دو نوع عملگر سهتایی و عملگر nil-coalescing به این منظور وجود دارند. ما عملگرهای سهتایی را در مطلب بعدی بررسی خواهیم کرد و فعلاً عملگر nil-coalescing را با یک مثال معرفی میکنیم:
1var possibleAge: Int? = 26
2let age: Int = possibleAge ?? 0
عملگر nil-coalescing به صورت ?? برای بررسی این وضعیت استفاده میشود که آیا مقدار سمت چپ، تهی است یا نه. اگر چنین باشد میتوانیم مقدار پیشفرض را در سمت راست تعیین کنیم. در مثال فوق، age با استفاده از مقدار 26 وهلهسازی میشود، چون ما میتوانیم یک مقدار را از possibleAge بگیریم.
1var possibleAge: Int?
2let age: Int = possibleAge ?? 0
با این وجود در این مثال age برابر با 0 تعیین خواهد شد، زیرا possibleAge هرگز تعیین نشده است و سمت چپ تساوی برابر با nil ارزیابی میشود. با این که این مثال درک این مفهوم را تسهیل میکند؛ اما در اغلب موارد ممکن است خطوط کد زیادی بین مکانی که مقدار را تعیین میکنید و مقداری که از آن استفاده میکنید وجود داشته باشد و از این رو شما در عمل صرفاً کدی با وضعیت زیر را مشاهده میکنید:
let data: String = possibleData?? "No data found"
اینک سؤال این است که آیا possibleData مقداری دارد یا نه؟ چه میشود اگر این دادهها را از وب بگیریم؟ ما تا زمانی که به محیط زمان اجرا (runtime) نرویم یا تا هنگامی که اپلیکیشن اجرا نشده است، نمیتوانیم به این سؤالها پاسخ بدهیم. عملگر nil-coalescing در این جا به خوبی ایفای نقش میکند زیرا امکان مدیریت مواردی که possibleData ممکن است یک مقدار داشته باشد یا نداشته باشد را فراهم میسازد.
سخن پایانی
بدین ترتیب به پایان یک بخش دیگر از سری مقالات آموزش برنامهنویسی سوئیفت میرسیم. ما در این نوشته تقریباً با همه مفاهیم عملگرهای سوئیفت آشنا شدیم. مواردی نیز که جا ماندهاند در بخشهای بعدی این سری مقالات ارائه خواهند شد، چون برای یادگیری برخی از این موارد باید قبلاً مفاهیم دیگری را آموخته باشید.
در این نوشته همچنین با optional-ها آشنا شدیم و برخی کاربردهای آنها را یاد گرفتیم. مقادیر تهی و روش مدیریت آنها نیز ارائه شدهاند.
در بخش بعدی این نوشته در مورد تصمیمگیری در برنامهها و حلقهها صحبت خواهیم کرد. بدین ترتیب مباحثی که تا اینجا مطرح شدند کمکم جمعبندی میشوند و میتوانید از آنها در عمل استفاده کنید. تمرین کردن مفاهیم آموزش داده شده را فراموش نکنید، چون تمرین در برنامهنویسی بخش بزرگی از آموزش را شامل میشود.
برای مطالعه قسمت بعدی این مجموعه آموزش روی لینک زیر کلیک کنید:
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- آموزش برنامه نویسی Swift (سوئیفت) برای برنامه نویسی iOS
- مجموعه آموزش های پروژه محور برنامه نویسی
- آموزش آرایه در برنامه نویسی Swift (سوئیفت)
- آرایه ها در زبان برنامه نویسی سوئیفت (Swift) — به زبان ساده
- آموزش برنامه نویسی سوئیفت (Swift): متغیر، ثابت و انواع داده
==