هسته core
متوقف کردن برنامه با یک پیام روشن، و اختیاری برای مقداری که ممکن است باشد یا نباشد.
واردسازی هسته
نام آرگومانها شناسهی خود کد است و معادل فارسی ندارد؛ گونهها، کلیدواژهها و نام بستهها با معادل فارسی نوشته میشوند.
بستهی هسته فقط یک تابع دارد، اما تابع مهمی است. گاهی برنامه به جایی میرسد که ادامه دادن معنا ندارد: دادهای خراب است یا شرطی که «هرگز نباید پیش بیاید» پیش آمده. در این حالت بهتر است برنامه همانجا با یک پیام روشن بایستد تا اینکه بیصدا نتیجهی غلط تحویل دهد.
برای خطاهای عادی، مثل ورودی نادرست کاربر، تابع را خطادار کنید و یک خطا پرتاب خطا کنید تا صدازننده خودش با تلاش و گرفتن خطا تصمیم بگیرد. خطای مرگبار برای جایی است که هیچ راه درستی برای ادامه نمانده، و گرفتن خطا جلویش را نمیگیرد.
هسته گونههای خطای داخلی، خطا و نوع خطا، را هم تعریف میکند که هر برنامهای بدون واردسازی میتواند از آنها استفاده کند. بستهی خطا توضیح میدهد چطور آنها را پرتاب کنید، بالا بفرستید و بگیرید.
نگهبانی از یک قاعدهی همیشگی
قاعدهی همیشگی چیزی است که خود کد شما قول میدهد همیشه درست بماند: موجودی حساب هیچوقت منفی نمیشود، فهرست همیشه مرتب است، شمارهی خانه از اندازه بیرون نمیزند. برای شکستهای عادی و قابل پیشبینی، مقداری برمیگردانید که صدازننده بتواند با آن کاری کند. اما اگر قاعدهی همیشگی شکسته شود، ایراد در خود برنامه است و هر نتیجهای که از آن به بعد حساب شود غلط است؛ آنجا جای خطای مرگبار است.
واردسازی هسته
ساختار حساب:
همگانی صاحب: رشته = ""
همگانی موجودی: صحیح = ۰
پایان
تابع برداشت(ح &: حساب، مبلغ: صحیح): منطقی:
اگر مبلغ > ح.موجودی:
برگشت نادرست
پایان
ح.موجودی -= مبلغ
اگر ح.موجودی < ۰:
هسته.خطای مرگبار("موجودی حساب " + ح.صاحب + " منفی شد")
پایان
برگشت درست
پایان
تابع ریشه:
ناپایا ح := حساب { صاحب = "سارا"، موجودی = ۱۰۰ }
سرچاپ برداشت(ح، ۳۰)، ح.موجودی
سرچاپ برداشت(ح، ۵۰۰)، ح.موجودی
سرچاپ برداشت(ح، ۷۰)، ح.موجودی
پایاندرخواست برداشتی بیشتر از موجودی یک وضعیت عادی است، پس برداشت فقط نادرست برمیگرداند. خطای مرگبار بعد از تفریق تنها وقتی اجرا میشود که کسی بعدها تابع را تغییر دهد و خرابش کند. کارش این است که آن اشتباه همان لحظه و با نام صاحب حساب در پیام دیده شود، نه چند هفته بعد به شکل یک عدد عجیب.
علامت گذاشتن روی کدی که نباید اجرا شود
تابعی که برای هر ورودی باید مقداری برگرداند، بعد از همهی حالتهای شناختهشده هم به چیزی در انتها نیاز دارد. وقتی ورودیهای باقیمانده بنا به طراحی ناممکناند، صادقانهترین پایان یک خطای مرگبار است که مقدار نادرست را در پیامش دارد. یک مقدار ساختگی، مثل رشتهی خالی، ایراد را پنهان میکند و میگذارد جلوتر برود.
واردسازی هسته
تابع چراغ بعدی(چراغ: رشته): رشته:
ترابرد چراغ:
"قرمز":
برگشت "سبز"
پایان
"سبز":
برگشت "زرد"
پایان
"زرد":
برگشت "قرمز"
پایان
پایان
هسته.خطای مرگبار("چراغ ناشناخته: " + چراغ)
پایان
تابع ریشه:
ناپایا چراغ := "قرمز"
تکرار ۴:
بعدی := چراغ بعدی(چراغ)
سرچاپ چراغ، "سپس"، بعدی
چراغ = بعدی
پایان
پایانچون خطای مرگبار هیچوقت برنمیگردد، مترجم آن را بهعنوان آخرین دستور تابعی که نوع خروجی دارد میپذیرد. مقدار غیرمنتظره را در پیام بگذارید: چراغ ناشناخته: آبی خیلی بیشتر از «نباید به اینجا میرسید» به شما میگوید.
وقتی حالتها عضوهای یک شمارشیاند، همخوان بهتر است: باید همهی عضوها را پوشش دهد، پس مترجم حالت جاافتاده را خودش پیدا میکند و نیازی به خطای مرگبار نیست.
خطای مرگبار، یا مقداری که شکست را گزارش میدهد؟
این دو کنار هم کار میکنند. هرچه از بیرون برنامه میآید، مثل ورودی کاربر، پرونده، شبکه یا یک سرویس دیگر، در کار عادی هم ممکن است نادرست باشد؛ پس تابع را خطادار کنید و بگذارید صدازننده با تلاش و گرفتن خطا تصمیم بگیرد، یا مقداری برگردانید که خودش شکست را حمل میکند، مثل یک شمارشی که خودتان با یک عضو خطا تعریف میکنید و عملگر ? روی آن. وقتی مقدار یک بار بررسی شد، تابعهای درونی میتوانند مقدار نادرست را اشتباه برنامهنویس بدانند و برنامه را متوقف کنند.
واردسازی هسته
جداشمار نتیجه<ت، خ>:
موفق(مقدار: ت)
خطا(پیام: خ)
پایان
تابع خواندن درصد(متن: رشته): نتیجه<صحیح، رشته>:
ع := متن.به صحیح()
اگر ع < ۰ یا ع > ۱۰۰:
برگشت نتیجه.خطا("درصد باید بین ۰ تا ۱۰۰ باشد، رسید: " + متن)
پایان
برگشت نتیجه.موفق(ع)
پایان
تابع اعمال تخفیف(قیمت: صحیح، درصد: صحیح): صحیح:
اگر درصد < ۰ یا درصد > ۱۰۰:
هسته.خطای مرگبار("اعمال تخفیف با درصد " + درصد + " صدا زده شد")
پایان
برگشت قیمت - قیمت * درصد / ۱۰۰
پایان
تابع ریشه:
هر نوشته در ["۲۰"، "۲۵۰"]:
ن := خواندن درصد(نوشته)
همخوان ن:
موفق(د): سرچاپ "قیمت پس از تخفیف:"، اعمال تخفیف(۸۰، د) پایان
خطا(پیام): سرچاپ "پذیرفته نشد:"، پیام پایان
پایان
پایان
پایان| وضعیت | ابزار |
|---|---|
| کاربر چیز نادرستی نوشته | خطادار و پرتاب خطا یک خطا |
| پرونده یا سرور در دسترس نیست | خطادار، یا پارامتر خروجی خطا در همان بسته |
| مقدار ممکن است اصلاً نباشد | اختیاری، در پایین، یا فیلدی به شکل T؟ |
| کد خودتان قاعدهای را که قول داده شکسته | خطای مرگبار |
| حالتی که بنا به طراحی پیش نمیآید | خطای مرگبار، یا همخوان روی یک شمارشی |
خطای مرگبار دقیقاً چه میکند
- عبارت
salam panic:و پیام شما را در خروجی خطا مینویسد و بعد تابعabortزبان C را صدا میزند. فرایند با سیگنالSIGABRTتمام میشود که پوسته آن را کد خروج ۱۳۴ نشان میدهد، و ممکن است سیستمعامل یک core dump هم بنویسد. - دستورهای
دیرکناجرا نمیشوند؛ پس پروندههای باز کامل نوشته نمیشوند و پروندههای موقت میمانند. - متنی که برنامه پیش از خطا چاپ کرده اول نوشته میشود، حتی اگر خروجی استاندارد به یک لوله یا پرونده برود و
سرچاپآن را هنوز در میانگیر نگه داشته باشد؛ پس پیام خطای مرگبار بعد از آخرین خط چاپشده میآید. - در یک سرور، یک درخواست خراب که به خطای مرگبار برسد بقیهی درخواستها را هم از کار میاندازد.
دلیل اصلی اینکه خطای مرگبار را فقط برای ایرادهای واقعی نگه داریم همین است.
اختیاری: مقداری که ممکن است باشد یا نباشد
گاهی جواب یک تابع «هیچ» است: جستجو چیزی پیدا نکرده یا تنظیمی تعریف نشده. برگرداندن منفی یک یا رشتهی تهی برای این حالت راحت است، اما بعداً فراموش میشود و باگ میسازد. اختیاری<T> این را صریح میکند: یا یک مقدار از گونهی T دارد، یا ندارد. T؟ شکل کوتاه هسته.اختیاری<T> است و به واردسازی نیاز ندارد: فیلدی که مهلت: صحیح؟ نوشته شده را میشود در مقدار ساختاری ننوشت، مقدار ساده خودکار در آن قرار میگیرد و پوچ یعنی خالی. فیلدهای اختیاری را ببینید.
اختیارییک ساختار ساده با دو فیلدvalueوpresentاست، نه یک جداشمار: آن را بادارد()یا.presentبررسی میکنید، نه باهمخوان، و عملگر?روی آن کار نمیکند.- هیچوقت پیش از بررسی سراغ
.valueنروید. در اختیاری خالی، این فیلد مقدار صفر گونهیTاست: برای عدد صفر، ولی برایرشتهیک اشارهگر پوچ که چاپ کردن یا گرفتن طولش برنامه را از کار میاندازد. - اختیاری را فقط با
یک مقداروهیچ مقداربسازید (یا با مقدار ساده وپوچاز راهT؟) تا دو فیلدش همیشه با هم جور باشند. - تابعهای آزاد
یک مقدار،هیچ مقدار،دارد،ندارد،یابرگردان،بازکنوانتظاربهواردسازی هستهو پیشوندهسته.نیاز دارند؛ روشهایدارد()،ندارد()،یابرگردان(پ)وبازکن()روی مقداری که از پیشT؟است، به هیچکدام نیاز ندارند.
جستوجویی که ممکن است چیزی پیدا نکند
جستوجو نمونهی کلاسیک کاربرد اختیاری است. برگرداندن رشتهی خالی برای شمارهی تلفنی که نیست دوپهلوست، چون ممکن است یک مقدار خالی عمداً ذخیره شده باشد. تابعی که رشته؟ برمیگرداند در خود امضایش روشن میگوید که جواب ممکن است نباشد، و هر صدازنندهای باید این را در نظر بگیرد.
تابع شمارهی تلفن(دفترچه: نگاشت<رشته، رشته>، نام: رشته): رشته؟:
اگر دفترچه.دارد(نام):
برگشت دفترچه.بگیر(نام)
پایان
برگشت پوچ
پایان
تابع ریشه:
ناپایا دفترچه := نگاشت {} برگردان نگاشت<رشته، رشته>
دیرکن دفترچه.آزادکن()
دفترچه.درج("سارا"، "۰۹۱۲ ۱۱۱ ۲۲۳۳")
دفترچه.درج("امید"، "۰۹۳۵ ۴۴۴ ۵۵۶۶")
هر نام در ["امید"، "ندا"]:
ت := شمارهی تلفن(دفترچه، نام)
اگر ت.دارد():
سرچاپ نام + ":"، ت.مقدار
وگرنه:
سرچاپ نام + ": شمارهای ثبت نشده"
پایان
پایان
سرچاپ "تماس با"، شمارهی تلفن(دفترچه، "ندا").یابرگردان("پذیرش")
پایاندارد() و پس از آن .value برای کدی مناسب است که در دو حالت دو کار متفاوت میکند. وقتی پیشفرض معقولی هست، یابرگردان بررسی و جایگزین را در یک فراخوانی انجام میدهد، همانطور که خط آخر نشان میدهد.
تنظیمات اختیاری با مقدار پیشفرض
فیلد اختیاری «داده نشده» را از صفرِ واقعی یا رشتهی خالی جدا میکند؛ کاری که از یک فیلد صحیح ساده برنمیآید. پیشفرض هر فیلد اختیاری را پوچ بگذارید تا بشود آن را در ساختن ساختار ننوشت، و پیشفرض واقعی را همانجا که مقدار به کار میرود اعمال کنید.
ساختار تنظیمات:
همگانی پهنا: صحیح؟ = پوچ
همگانی عنوان: رشته؟ = پوچ
پایان
تابع شرح(ت: تنظیمات): رشته:
پ := ت.پهنا.یابرگردان(۸۰)
ع := ت.عنوان.یابرگردان("بینام")
برگشت ع + " (" + پ + " ستون)"
پایان
تابع ریشه:
سرچاپ شرح(تنظیمات {})
سرچاپ شرح(تنظیمات { پهنا = ۱۲۰ })
سرچاپ شرح(تنظیمات { پهنا = ۰، عنوان = "گزارش" })
پایانخط سوم نشان میدهد چرا این مهم است: پهنای صفر عمداً داده شده و همان میماند، در حالی که دو خط اول به ۸۰ برمیگردند.
جستوجو در فهرستی از ساختارها
جستوجو در یک وکتور نخستین مورد پیداشده را برمیگرداند یا هیچ. اینجا برنامه میداند که در آن لحظه حتماً یک کار باز هست، پس از هسته.انتظار استفاده میکند: اگر این فرض روزی غلط از آب درآید، برنامه با همان جمله میایستد، نه اینکه با یک نام خالی ادامه دهد.
واردسازی هسته
ساختار کار:
همگانی نام: رشته = ""
همگانی انجام شده: منطقی = نادرست
پایان
تابع نخستین کار باز(کارها: وکتور<کار>): رشته؟:
هر ک در کارها:
اگر وارونه ک.انجام شده:
برگشت ک.نام
پایان
پایان
برگشت پوچ
پایان
تابع ریشه:
ناپایا کارها := وکتور {} برگردان وکتور<کار>
دیرکن کارها.آزادکن()
کارها.بیفزا(کار { نام = "نوشتن آزمونها"، انجام شده = درست })
کارها.بیفزا(کار { نام = "رفع ایراد ورود" })
کارها.بیفزا(کار { نام = "بهروزرسانی راهنما" })
بعدی := نخستین کار باز(کارها)
سرچاپ "کار بعدی:"، هسته.انتظار(بعدی، "اینجا همیشه یک کار باز هست")
هر ش، ک در کارها:
کارها.بنشان(ش، کار { نام = ک.نام، انجام شده = درست })
پایان
سرچاپ "کاری مانده؟"، نخستین کار باز(کارها).دارد()
پایانهسته.بازکن وقتی اختیاری خالی باشد با پیامی کلی میایستد. هسته.انتظار بهتر است، چون پیامش به خواننده میگوید کدام فرض شکسته، و همان قاعدهی خطای مرگبار در بالا را دارد: فقط برای فرضهایی که شکستنشان ایراد خود برنامه است. وقتی صدازننده باید بداند چرا چیزی شکست، نه فقط اینکه مقداری نیست، تابع را خطادار کنید یا شمارشی خودتان را با یک عضو خطا بسازید.
گونهها
نوع خطا ErrorKind
جداشمار نوع خطا| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| دیگر | Other | | هر خطایی که در هیچ نوع دیگری نمیگنجد. پرتاب خطا "پیام" این نوع را میگیرد. |
| نحو | Syntax | | ورودی از قالب خودش پیروی نمیکند، مثل ویرگول جاافتاده در جیسون. |
| اتمام ناگهانی | UnexpectedEnd | | ورودی وسط یک مقدار تمام شده است. |
| ناهمخوانی نوع | TypeMismatch | | مقداری گونهای غیر از گونهی خواستهشده دارد. |
| کلید ناموجود | MissingKey | | کلید یا فیلد لازمی وجود ندارد. |
| خارج از بازه | OutOfRange | | عدد، نمایه یا اندازهای بیرون از بازهی مجاز است. |
| یوتیاف۸ نامعتبر | InvalidUtf8 | | متن یوتیاف۸ معتبر نیست. |
| آرگومان نامعتبر | InvalidArgument | | فراخوان مقداری داده که تابع نمیتواند بپذیرد. |
| یافت نشد | NotFound | | چیزی که خواسته شده وجود ندارد. |
| از قبل موجود | AlreadyExists | | چیزی که باید تازه باشد از قبل هست. |
| دسترسی رد شد | PermissionDenied | | این کار مجاز نیست. |
| ورودی خروجی | Io | | خواندن یا نوشتن شکست خورده؛ تلاش دوباره ممکن است جواب دهد. |
| اتمام زمان | Timeout | | زمان تمام شده؛ تلاش دوباره ممکن است جواب دهد. |
| لغو شد | Canceled | | کار عمداً متوقف شده است. |
| ناموجود | Unavailable | | سرویسی فعلاً در دسترس نیست؛ تلاش دوباره ممکن است جواب دهد. |
| پشتیبانی نشده | Unsupported | | ورودی یا درخواست از چیزی استفاده میکند که پشتیبانی نمیشود. |
| داخلی | Internal | | ایرادی درون خود برنامه. |
تابع تکرارپذیر(خ: خطا): منطقی:
برگشت خ.است(نوع خطا.ورودی خروجی) یا خ.است(نوع خطا.اتمام زمان) یا خ.است(نوع خطا.ناموجود)
پایان
تابع ریشه:
دستهها := [نوع خطا.ورودی خروجی، نوع خطا.اتمام زمان، نوع خطا.ناموجود، نوع خطا.یافت نشد، نوع خطا.دسترسی رد شد، نوع خطا.داخلی]
هر دسته در دستهها:
خ := خطا.جدید(دسته، "شکست خورد")
اگر تکرارپذیر(خ):
سرچاپ خ.نام نوع() + ": دوباره تلاش کنید"
وگرنه:
سرچاپ خ.نام نوع() + ": رها کنید"
پایان
پایان
پایانخطا Error
ساختار خطاپرتاب خطا میفرستد و گرفتن خطا دریافت میکند. فقط متن و عدد نگه میدارد، پس رونوشتگرفتن از آن ارزان و بیخطر است.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نوع | kind | نوع خطا | دستهی کلی، یکی از نوع خطا. |
| کد | code | رشته = "" | کدی دقیق که بستهی پرتابکننده انتخاب کرده، مثل json.trailing_data؛ اگر نباشد خالی است. |
| پیام | message | رشته = "" | اینکه چه پیش آمده، برای خواندن انسان. |
| زمینه | context | رشته = "" | توضیحهایی که بپیچ افزوده، بیرونیترین اول، با «: » کنار هم. |
| مسیر | path | رشته = "" | جای مشکل در داده، مثل $.users[3].age، یا مسیر یک پرونده؛ اگر معلوم نباشد خالی است. |
| جایگاه | offset | صحیح = -1 | جایگاه بایتی مشکل در ورودی، یا ۱- اگر معلوم نباشد. |
| خط | line | صحیح = 0 | شمارهی خط مشکل، از ۱، یا ۰ اگر معلوم نباشد. |
| ستون | column | صحیح = 0 | شمارهی ستون مشکل، از ۱، یا ۰ اگر معلوم نباشد. |
تابع سن خوانی(متن: رشته): صحیح خطادار:
اگر متن == "":
پرتاب خطا خطا.جدید(نوع خطا.کلید ناموجود، "سن داده نشده است")
پایان
ن := متن.به صحیح()
اگر ن < ۰ یا ن > ۱۵۰:
پرتاب خطا خطا.جدید(نوع خطا.خارج از بازه، "سن " + ن + " خارج از بازه است").با کد("age.range")
پایان
برگشت ن
پایان
تابع ریشه:
هر متن در ["42"، ""، "200"]:
تلاش:
سرچاپ "سن"، سن خوانی(متن)
گرفتن خطا خ:
سرچاپ خ.نام نوع() + ":"، خ.پیام
سرچاپ " کد:"، خ.کد، "| خارج از بازه:"، خ.است(نوع خطا.خارج از بازه)
پایان
پایان
خ := خطا.در جایگاه(نوع خطا.نحو، "رقم انتظار میرفت"، ۴).با مسیر("$.age")
سرچاپ خ.به رشته()
جادار := خ.با موقعیت(۴، ۲، ۳).بپیچ("خواندن فرم")
سرچاپ جادار.به رشته()
سرچاپ جادار.جایگاه، جادار.خط، جادار.ستون، جادار.زمینه
پایاناست Is
تابع است(kind: نوع خطا): منطقیاست is
تابع است(kind: نوع خطا): منطقیتابع خواندن یادداشت(نام: رشته): رشته خطادار:
اگر نام == "":
پرتاب خطا خطا.جدید(نوع خطا.آرگومان نامعتبر، "نام خالی است")
پایان
اگر نام != "notes.txt":
پرتاب خطا خطا.جدید(نوع خطا.یافت نشد، نام + " وجود ندارد")
پایان
برگشت "محتوای " + نام
پایان
تابع ریشه:
هر نام در ["notes.txt"، "todo.txt"، ""]:
تلاش:
سرچاپ خواندن یادداشت(نام)
گرفتن خطا خ:
اگر خ.است(نوع خطا.یافت نشد):
سرچاپ "اول بسازیدش:"، خ.پیام
وگرنه:
سرچاپ "نمیشود ادامه داد:"، خ.پیام
پایان
پایان
پایان
پایانبپیچ Wrap
تابع بپیچ(message: رشته): خطابپیچ wrap
تابع بپیچ(message: رشته): خطاتابع خواندن درگاه(متن: رشته): صحیح خطادار:
ن := متن.به صحیح()
اگر ن < ۱ یا ن > ۶۵۵۳۵:
پرتاب خطا خطا.جدید(نوع خطا.خارج از بازه، "درگاه " + ن + " معتبر نیست")
پایان
برگشت ن
پایان
تابع بارگذاری پیکربندی(متن: رشته): صحیح خطادار:
تلاش:
برگشت خواندن درگاه(متن)
گرفتن خطا خ:
پرتاب خطا خ.بپیچ("خواندن درگاه")
پایان
پایان
تابع ریشه:
تلاش:
سرچاپ بارگذاری پیکربندی("80")
سرچاپ بارگذاری پیکربندی("70000")
گرفتن خطا خ:
سرچاپ خ.به رشته()
سرچاپ "زمینه:"، خ.زمینه
سرچاپ "نوع:"، خ.نام نوع()
پایان
پایانبا کد WithCode
تابع با کد(code: رشته): خطابا کد with_code
تابع با کد(code: رشته): خطاتابع سن خوانی(متن: رشته): صحیح خطادار:
ن := متن.به صحیح()
اگر ن < ۰ یا ن > ۱۵۰:
پرتاب خطا خطا.جدید(نوع خطا.خارج از بازه، "سن " + ن + " خارج از بازه است").با کد("age.range")
پایان
برگشت ن
پایان
تابع ریشه:
هر متن در ["30"، "200"]:
تلاش:
سرچاپ "سن"، سن خوانی(متن)
گرفتن خطا خ:
اگر خ.کد == "age.range":
سرچاپ "دوباره بپرسید:"، خ.پیام
پایان
سرچاپ "کد:"، خ.کد
پایان
پایان
پایانبا مسیر WithPath
تابع با مسیر(path: رشته): خطابا مسیر with_path
تابع با مسیر(path: رشته): خطاتابع بررسی(کاربر: رشته، سن: صحیح): صحیح خطادار:
اگر سن < ۱۸:
پرتاب خطا خطا.جدید(نوع خطا.خارج از بازه، "باید دستکم ۱۸ باشد").با مسیر("$.users[" + کاربر + "].age")
پایان
برگشت سن
پایان
تابع ریشه:
تلاش:
سرچاپ بررسی("sara"، ۳۱)
سرچاپ بررسی("omid"، ۱۲)
گرفتن خطا خ:
سرچاپ خ.به رشته()
سرچاپ "کجا:"، خ.مسیر
پایان
پایانبا موقعیت WithPosition
تابع با موقعیت(offset: صحیح، line: صحیح، column: صحیح): خطابا موقعیت with_position
تابع با موقعیت(offset: صحیح، line: صحیح، column: صحیح): خطاتابع ریشه:
متن := "name = Sara\nage = ?\n"
جا := متن.بیاب("?")
شروع خط := متن.بیاب("age")
ستون := جا - شروع خط + ۱
خ := خطا.جدید(نوع خطا.نحو، "عدد انتظار میرفت").با موقعیت(جا، ۲، ستون)
سرچاپ خ.به رشته()
سرچاپ خ.جایگاه، خ.خط، خ.ستون
پایانمکان یابی Locate
تابع مکان یابی(text: رشته): خطامکان یابی locate
تابع مکان یابی(text: رشته): خطاخط و ستون آن از روی جایگاه در متن دادهشده، یعنی همان ورودیای که خطا در آن پیدا شده، حساب شده است. خط و ستون از ۱ شمرده میشوند و ستون نویسهها را میشمارد، نه بایتها را. خطای بیجایگاه بیتغییر برمیگردد.تابع ریشه:
متن := "name = shop\nport = eighty\n"
خ := خطا.در جایگاه(نوع خطا.نحو، "یک عدد لازم است"، ۱۹)
سرچاپ خ.خط، خ.ستون
یافته := خ.مکان یابی(متن)
سرچاپ یافته.خط، یافته.ستون
سرچاپ یافته.به رشته()
پایاننام نوع KindName
تابع نام نوع(): رشتهنام نوع kind_name
تابع نام نوع(): رشتهتابع ریشه:
هر دسته در [نوع خطا.یافت نشد، نوع خطا.خارج از بازه، نوع خطا.اتمام زمان، نوع خطا.دسترسی رد شد، نوع خطا.دیگر]:
خ := خطا.جدید(دسته، "جزئیات")
سرچاپ خ.نام نوع()
پایان
پایانبه رشته ToStr
تابع به رشته(): رشتهبه رشته to_str
تابع به رشته(): رشتهسرچاپ هم از آن استفاده میکند.تابع ریشه:
ساده := خطا.جدید(نوع خطا.اتمام زمان، "سرور پاسخ نداد")
سرچاپ ساده.به رشته()
خالی := خطا.جدید(نوع خطا.یافت نشد، "")
سرچاپ خالی.به رشته()
جایی := خطا.جدید(نوع خطا.نحو، "ویرگول جا افتاده").با مسیر("$.items[2]").با موقعیت(۴۰، ۳، ۹)
سرچاپ جایی.به رشته()
پیچیده := جایی.بپیچ("خواندن سفارش").بپیچ("رسیدگی به درخواست")
سرچاپ پیچیده.به رشته()
پایانجدید New
ایستا تابع جدید(kind: نوع خطا، message: رشته): خطاپرتاب خطا میفرستد.تابع یافتن کاربر(شناسه: صحیح): رشته خطادار:
اگر شناسه != ۱:
پرتاب خطا خطا.جدید(نوع خطا.یافت نشد، "کاربری با شناسهی " + شناسه + " نیست")
پایان
برگشت "سارا"
پایان
تابع ریشه:
هر شناسه در [۱، ۷]:
تلاش:
سرچاپ "پیدا شد"، یافتن کاربر(شناسه)
گرفتن خطا خ:
سرچاپ خ.نام نوع() + ":"، خ.پیام
پایان
پایان
پایاندر جایگاه At
ایستا تابع در جایگاه(kind: نوع خطا، message: رشته، offset: صحیح): خطاجدید، و جایگاه بایتی مشکل در ورودی را هم ثبت میکند.تابع رقم(متن: رشته، جا: صحیح): صحیح خطادار:
ک := متن.زیررشته(جا، ۱)
اگر ک < "0" یا ک > "9":
پرتاب خطا خطا.در جایگاه(نوع خطا.نحو، "رقم انتظار میرفت"، جا)
پایان
برگشت ک.به صحیح()
پایان
تابع ریشه:
متن := "12x4"
تکرار متن.طول() در ن:
تلاش:
سرچاپ "رقم"، رقم(متن، ن)
گرفتن خطا خ:
سرچاپ خ.به رشته()
سرچاپ "جایگاه"، خ.جایگاه
پایان
پایان
پایاننتیجه پرتاب Throws
گونه نتیجه پرتاب = گوناگون<auto<T>، auto<T>>خطادار در پشت صحنه برمیگرداند. هیچوقت آن را نمینویسید: تلاش و گرفتن خطا آن را برایتان باز میکنند.Tuple2
ساختار Tuple2<A، B>(A, B): دو مقدار که کنار هم نگه داشته میشوند. نام آن را هرگز نمینویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی میسازد و x، y := f() آن را باز میکند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| f0 | f0 | A | عنصر اول، که به شکل t.0 هم نوشته میشود. |
| f1 | f1 | B | عنصر دوم، که به شکل t.1 هم نوشته میشود. |
Tuple3
ساختار Tuple3<A، B، C>(A, B, C): سه مقدار که کنار هم نگه داشته میشوند. نام آن را هرگز نمینویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی میسازد و x، y := f() آن را باز میکند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| f0 | f0 | A | عنصر اول، که به شکل t.0 هم نوشته میشود. |
| f1 | f1 | B | عنصر دوم، که به شکل t.1 هم نوشته میشود. |
| f2 | f2 | C | عنصر سوم، که به شکل t.2 هم نوشته میشود. |
Tuple4
ساختار Tuple4<A، B، C، D>(A, B, C, D): چهار مقدار که کنار هم نگه داشته میشوند. نام آن را هرگز نمینویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی میسازد و x، y := f() آن را باز میکند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| f0 | f0 | A | عنصر اول، که به شکل t.0 هم نوشته میشود. |
| f1 | f1 | B | عنصر دوم، که به شکل t.1 هم نوشته میشود. |
| f2 | f2 | C | عنصر سوم، که به شکل t.2 هم نوشته میشود. |
| f3 | f3 | D | عنصر چهارم، که به شکل t.3 هم نوشته میشود. |
Tuple5
ساختار Tuple5<A، B، C، D، E>(A, B, C, D, E): پنج مقدار که کنار هم نگه داشته میشوند. نام آن را هرگز نمینویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی میسازد و x، y := f() آن را باز میکند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| f0 | f0 | A | عنصر اول، که به شکل t.0 هم نوشته میشود. |
| f1 | f1 | B | عنصر دوم، که به شکل t.1 هم نوشته میشود. |
| f2 | f2 | C | عنصر سوم، که به شکل t.2 هم نوشته میشود. |
| f3 | f3 | D | عنصر چهارم، که به شکل t.3 هم نوشته میشود. |
| f4 | f4 | E | عنصر پنجم، که به شکل t.4 هم نوشته میشود. |
Tuple6
ساختار Tuple6<A، B، C، D، E، F>(A, B, C, D, E, F): شش مقدار که کنار هم نگه داشته میشوند. نام آن را هرگز نمینویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی میسازد و x، y := f() آن را باز میکند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| f0 | f0 | A | عنصر اول، که به شکل t.0 هم نوشته میشود. |
| f1 | f1 | B | عنصر دوم، که به شکل t.1 هم نوشته میشود. |
| f2 | f2 | C | عنصر سوم، که به شکل t.2 هم نوشته میشود. |
| f3 | f3 | D | عنصر چهارم، که به شکل t.3 هم نوشته میشود. |
| f4 | f4 | E | عنصر پنجم، که به شکل t.4 هم نوشته میشود. |
| f5 | f5 | F | عنصر ششم، که به شکل t.5 هم نوشته میشود. |
Tuple7
ساختار Tuple7<A، B، C، D، E، F، G>(A, B, C, D, E, F, G): هفت مقدار که کنار هم نگه داشته میشوند. نام آن را هرگز نمینویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی میسازد و x، y := f() آن را باز میکند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| f0 | f0 | A | عنصر اول، که به شکل t.0 هم نوشته میشود. |
| f1 | f1 | B | عنصر دوم، که به شکل t.1 هم نوشته میشود. |
| f2 | f2 | C | عنصر سوم، که به شکل t.2 هم نوشته میشود. |
| f3 | f3 | D | عنصر چهارم، که به شکل t.3 هم نوشته میشود. |
| f4 | f4 | E | عنصر پنجم، که به شکل t.4 هم نوشته میشود. |
| f5 | f5 | F | عنصر ششم، که به شکل t.5 هم نوشته میشود. |
| f6 | f6 | G | عنصر هفتم، که به شکل t.6 هم نوشته میشود. |
Tuple8
ساختار Tuple8<A، B، C، D، E، F، G، H>(A, B, C, D, E, F, G, H): هشت مقدار که کنار هم نگه داشته میشوند. نام آن را هرگز نمینویسید: (صحیح، رشته) همین ساختار است، برگشت الف، ب یکی میسازد و x، y := f() آن را باز میکند.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| f0 | f0 | A | عنصر اول، که به شکل t.0 هم نوشته میشود. |
| f1 | f1 | B | عنصر دوم، که به شکل t.1 هم نوشته میشود. |
| f2 | f2 | C | عنصر سوم، که به شکل t.2 هم نوشته میشود. |
| f3 | f3 | D | عنصر چهارم، که به شکل t.3 هم نوشته میشود. |
| f4 | f4 | E | عنصر پنجم، که به شکل t.4 هم نوشته میشود. |
| f5 | f5 | F | عنصر ششم، که به شکل t.5 هم نوشته میشود. |
| f6 | f6 | G | عنصر هفتم، که به شکل t.6 هم نوشته میشود. |
| f7 | f7 | H | عنصر هشتم، که به شکل t.7 هم نوشته میشود. |
اختیاری Option
ساختار اختیاری<T>یک مقدار یا هیچ مقدار بسازید تا دو فیلدش همیشه با هم جور باشند. معمولاً به شکل T؟ نوشته میشود.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| مقدار | value | T | خود مقدار. اگر present نادرست باشد، مقدار صفر گونهی T است؛ برای رشته یعنی اشارهگری پوچ که بهکار بردنش برنامه را از کار میاندازد، پس اول present را بررسی کنید. |
| موجود | present | منطقی | اگر مقداری در کار باشد، درست است. |
واردسازی هسته
تابع جستجو(نامها: وکتور<رشته>، دنبال: رشته): هسته.اختیاری<صحیح>:
هر ش، ن در نامها:
اگر ن == دنبال:
برگشت هسته.یک مقدار(ش)
پایان
پایان
برگشت هسته.هیچ مقدار()
پایان
تابع ریشه:
ناپایا نامها := وکتور {} برگردان وکتور<رشته>
دیرکن نامها.آزادکن()
نامها.بیفزا("علی")
نامها.بیفزا("مریم")
ی := جستجو(نامها، "مریم")
ن := جستجو(نامها، "رضا")
سرچاپ هسته.دارد(ی)، هسته.ندارد(ی)، ی.مقدار، ی.موجود
سرچاپ هسته.دارد(ن)، هسته.ندارد(ن)
سرچاپ هسته.باز کردن(ی)، هسته.انتظار(ی، "باید پیدا میشد")
سرچاپ هسته.با پیش فرض(ن، -۱)
پایاندارد IsSome
تابع دارد(): منطقیدارد is_some
تابع دارد(): منطقیدارد: اگر مقداری در کار باشد، درست است.ساختار مشتری:
همگانی مهلت: صحیح؟
پایان
تابع ریشه:
الف := مشتری { }
ب := مشتری { مهلت = ۳۰ }
سرچاپ الف.مهلت.دارد()، الف.مهلت.ندارد()، الف.مهلت.یابرگردان(۵)
سرچاپ ب.مهلت.دارد()، ب.مهلت.ندارد()، ب.مهلت.یابرگردان(۵)، ب.مهلت.بازکن()
پایانندارد IsNone
تابع ندارد(): منطقیندارد is_none
تابع ندارد(): منطقیندارد: اگر خالی باشد، درست است.نمونهی این مورد همراه با موارد بالاتر آمده است: core-Methods.salam
یابرگردان UnwrapOr
تابع یابرگردان(fallback: T): Tیابرگردان unwrap_or
تابع یابرگردان(fallback: T): Tیابرگردان: مقدار، یا اگر خالی باشد، جایگزینی که دادهاید.نمونهی این مورد همراه با موارد بالاتر آمده است: core-Methods.salam
بازکن Unwrap
تابع بازکن(): Tبازکن unwrap
تابع بازکن(): Tبازکن: مقدار، یا اگر خالی باشد، خطای مرگبار.نمونهی این مورد همراه با موارد بالاتر آمده است: core-Methods.salam
تابعها
خطای مرگبار Panic
تابع خطای مرگبار(msg: رشته)salam panic: و پیام را در خروجی خطا مینویسد و فرایند را با کد خروج ۱۳۴ از کار میاندازد. این تابع هیچوقت برنمیگردد و دستورهای دیرکن اجرا نمیشوند؛ خروجی استانداردی که برنامه پیش از آن چاپ کرده اول نوشته میشود. نمونهی زیر اجرا نمیشود، چون عمداً برنامه را از کار میاندازد؛ خروجیاش چیزی شبیه salam panic: تقسیم بر صفر ممکن نیست است.واردسازی هسته
تابع تقسیم(الف: صحیح، ب: صحیح): صحیح:
اگر ب == ۰:
هسته.خطای مرگبار("تقسیم بر صفر ممکن نیست")
پایان
برگشت الف / ب
پایان
تابع ریشه:
سرچاپ تقسیم(۱۰، ۲)
سرچاپ تقسیم(۱، ۰)
پایانیک مقدار Some
تابع یک مقدار<T>(x: T): اختیاری<T>نمونهی این مورد همراه با موارد بالاتر آمده است: core-Option.salam
هیچ مقدار None
تابع هیچ مقدار<T>(): اختیاری<T>T از جایی که مقدار به کار میرود، مثلاً گونهی برگشتی تابع، معلوم میشود.نمونهی این مورد همراه با موارد بالاتر آمده است: core-Option.salam
دارد IsSome
تابع دارد<T>(o: اختیاری<T>): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: core-Option.salam
ندارد IsNone
تابع ندارد<T>(o: اختیاری<T>): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: core-Option.salam
با پیش فرض UnwrapOr
تابع با پیش فرض<T>(o: اختیاری<T>، fallback: T): Tنمونهی این مورد همراه با موارد بالاتر آمده است: core-Option.salam
انتظار Expect
تابع انتظار<T>(o: اختیاری<T>، msg: رشته): Tبازکن، ولی اگر خالی باشد با پیامی که خودتان دادهاید متوقف میشود؛ پیام خوب، پیدا کردن مشکل را آسان میکند.نمونهی این مورد همراه با موارد بالاتر آمده است: core-Option.salam
باز کردن Unwrap
تابع باز کردن<T>(o: اختیاری<T>): Tcalled Unwrap on a None value متوقف میشود.نمونهی این مورد همراه با موارد بالاتر آمده است: core-Option.salam