درس ۱۵ از ۲۵ · داده‌ها و گونه‌ها

جداشمارها

جداشمار گونه‌ای است با مجموعه‌ی بسته‌ای از حالت‌ها. حالت‌ها می‌توانند داده هم با خود داشته باشند.

جداشمار ساده

حالت‌ها با ویرگول جدا می‌شوند و از صفر شماره می‌گیرند؛ می‌توانید به هر حالت مقدار دلخواه بدهید و حالت‌های بعدی از همان‌جا ادامه می‌دهند. با برگردان صحیح شماره‌ی هر حالت را می‌گیرید.

enum-values.salam
جداشمار وضعیت:
    پیش‌نویس، منتشرشده = ۱۰، بایگانی
پایان

روال ریشه:
    حالت := وضعیت.منتشرشده
    سرچاپ حالت برگردان صحیح، وضعیت.بایگانی برگردان صحیح
    سرچاپ حالت == وضعیت.منتشرشده
پایان
خروجی10 11 true

.نام() نام هر حالت را به شکل رشته می‌دهد و .شمار() روی خود جداشمار، تعداد حالت‌ها را:

enum-name.salam
جداشمار فصل: بهار، تابستان، پاییز، زمستان پایان

روال ریشه:
    ف := فصل.پاییز
    سرچاپ ف.نام()
    سرچاپ "شمار فصل‌ها:", فصل.شمار()
    سرچاپ ف == فصل.پاییز, ف برگردان صحیح
پایان
خروجیپاییز شمار فصل‌ها: 4 true 2

جداشمار داده‌دار

هر حالت می‌تواند داده‌های نام‌دار داشته باشد، مثل شعاع برای دایره. با همخوان حالت را تشخیص دهید و داده‌هایش را بیرون بکشید. هر شاخه می‌تواند شرط اضافه‌ای با اگر داشته باشد؛ همخوان مطمئن می‌شود که همه‌ی حالت‌ها پوشش داده شده‌اند.

enum-data.salam
جداشمار شکل:
    دایره(شعاع: اعشار۶۴)
    مستطیل(پهنا: اعشار۶۴، بلندی: اعشار۶۴)
    هیچ
پایان

روال مساحت(ش: شکل): اعشار۶۴:
    برگشت همخوان ش:
        دایره(ر) => ۳.۱۴ * ر * ر
        مستطیل(پ، ب) اگر پ == ب => پ * پ
        مستطیل(پ، ب) => پ * ب
        هیچ => ۰.۰
    پایان
پایان

روال ریشه:
    سرچاپ مساحت(شکل.دایره(۲.۰))
    سرچاپ مساحت(شکل.مستطیل(۳.۰، ۴.۰))
    سرچاپ مساحت(شکل.هیچ)
    سرچاپ شکل.دایره(۱.۵)
پایان
خروجی12.56 12 0 دایره(شعاع = 1.5)

جداشمار عام

جداشمار داده‌دار هم می‌تواند گونه‌ی عام بگیرد. شاید<ت> یا مقداری دارد یا هیچ؛ راهی امن برای نشان دادن «نتیجه‌ای در کار نیست» بدون پوچ.

enum-generic.salam
جداشمار شاید<ت>:
    دارد(مقدار: ت)
    هیچ
پایان

روال تقسیم(الف: صحیح، ب: صحیح): شاید<صحیح>:
    اگر ب == ۰:
        برگشت شاید.هیچ
    پایان
    برگشت شاید.دارد(الف / ب)
پایان

روال شرح(ش: شاید<صحیح>): رشته:
    برگشت همخوان ش:
        دارد(م) => "حاصل " + م
        هیچ => "تقسیم بر صفر"
    پایان
پایان

روال ریشه:
    سرچاپ شرح(تقسیم(۱۰، ۲))
    سرچاپ شرح(تقسیم(۱، ۰))
پایان
خروجیحاصل 5 تقسیم بر صفر

نتیجه و عملگر ?

سلام استثنا ندارد. کتابخانه‌ی نتیجه جداشمار نتیجه<ت، خ> را دارد که یا Ok با مقدار است یا Err با خطا. درون روالی که نتیجه برمی‌گرداند، ? پس از یک فراخوانی مقدار درست را بیرون می‌کشد و اگر خطا بود، همان خطا را بی‌درنگ برمی‌گرداند.

result-try.salam
واردسازی نتیجه

روال عدد(م: رشته): نتیجه.نتیجه<صحیح، رشته>:
    اگر م == "۷":
        برگشت نتیجه.نتیجه.Ok(۷)
    پایان
    برگشت نتیجه.نتیجه.Err("عدد نامعتبر: " + م)
پایان

روال جمع(الف: رشته، ب: رشته): نتیجه.نتیجه<صحیح، رشته>:
    ا := عدد(الف)?
    ب۲ := عدد(ب)?
    برگشت نتیجه.نتیجه.Ok(ا + ب۲)
پایان

روال ریشه:
    سرچاپ جمع("۷"، "۷")
    سرچاپ جمع("۷"، "هفت")
پایان
خروجیOk(value = 14) Err(error = "عدد نامعتبر: هفت")