English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

الاستثناءات في Erlang

في أي لغة برمجة، تحتاج إلى معالجة الاستثناءات لمعالجة الأخطاء التنفيذية، حتى تتمكن من الحفاظ على تدفق التطبيق العادي. عادةً ما تؤدي الاستثناءات إلى انقطاع تدفق التطبيق العادي، لذا نحتاج إلى استخدام معالجة الاستثناءات في التطبيق.

عادةً، عندما يحدث استثناء أو خطأ في Erlang، سيتم عرض الرسالة التالية.

{"init terminating in do_boot", {undef,[{helloworld,start,[],[]}, 
{init,start_it,1,[]},{init,start_em,1,[]}]}}

سيتم كتابة التخزين الفشل إلى-

erl_crash.dump
init terminating in do_boot ()

في Erlang، هناك ثلاثة أنواع من الاستثناءات-

  • Error−يؤدي الاستدعاء إلى إنهاء تنفيذ عملية الحالي، ويشمل سجلاً للتوثيق عند إلتقاط أحدث دالة ومعرفاتها. هذه هي الاستثناءات التي تؤدي إلى الأخطاء التنفيذية المذكورة أعلاه.erlang:error(Reason)

  • Exists −هناك نوعان من الخروج: الخروج الداخلي والخروج الخارجي. يتم إطلاق الخروج الداخلي عن طريق استدعاء الدالة exit/1 مما يتوقف على تنفيذ عملية الحالي. يتم استدعاء الخروج الخارجي في exit/2 وهو يتعلق بمسائل التوازي في Erlang مع عدة عمليات.

  • Throw −throw هو نوع من الاستثناءات يستخدمه المبرمجين لمعالجة الحالات التي يمكنهم التعامل معها. بالمقارنة مع الخروج والإخطاء، فإنها لا تحمل أي 'عملية إنهاء!' الهدف وراءها، بل تتحكم في تدفقها. عندما تستخدم throw، من الأفضل عادةً تسجيل استخدامها في المodule الذي يستخدمها.

try... catch هي طريقة لحساب تعبير تسمح لك بمعالجة الحالات الناجحة بالإضافة إلى الأخطاء التي تواجهها.

نحو تعبير try-catch كما هو موضح أدناه.

النحو

try Expression of 
SuccessfulPattern1 [Guards] -> 
Expression1; 
SuccessfulPattern2 [Guards] -> 
Expression2 
catch TypeOfError:ExceptionPattern1 -> 
Expression3; 
TypeOfError:ExceptionPattern2 -> 
Expression4 
end

التعبير الذي يقع بين try و of يُدعى بالحماية. هذا يعني أن أي نوع من الاستثناءات التي تحدث أثناء هذه المكالمة سيتم إلتقاطها. نمط والتعبير بين try... و catch يتشابهان تمامًا في سلوكهما مع case...

في النهاية، جزء catch - هنا، يمكنك استبدال TypeOfError بـ error أو throw أو exit لكل نوع من الأنواع التي رأيتها في هذا الفصل. إذا لم يتم توفير النوع، يتم افتراض أنه يتم رمي.

Errorنوع الخطأ
badarg

خطأ في نوع البيانات للمعاملات، أو خطأ في الصيغة.

badarith

خطأ في المعاملات الرياضية.

{badmatch,V}

فشل تقييم تعبير التطابق.

function_clauseلم يتم العثور على الفرع الذي يتطابق مع استدعاء الدالة عند حسابه.
{case_clause,V}

لم يتم العثور على الفرع الذي يتطابق مع تعبير case عند حسابه.

if_clauseلم يتم العثور على الفرع الصحيح عند تقييم تعبير if.
{try_clause,V}

لم يتم العثور على الفقرة التي تطابق تعبير try عند حساب الفقرة.

undefلم يتم العثور على الدالة عند تقييم استدعاء الدالة.
{badfun,F}F الممتع ظهر بعض المشاكل
{badarit,F}

تم تطبيق المرح في عدد الأخطاء. F يصف المرح والجدل.

timeout_valueقيمة الزمن المحدد في تعبير receive..after يتم حسابها كأي شيء غير عدد صحيح أو لا نهائي.
noprocحاول الاتصال بمسار غير موجود.

فيما يلي مثال على كيفية استخدام هذه الاستثنائيات وكيفية التعامل معها.

  • الوظيفة الأولى توليد جميع أنواع الاستثنائيات الممكنة.

  • ثم نكتب دالة الحماية، في تعبير try...catch نستدعي generate_exception.

عينة عبر الإنترنت

-module(helloworld). 
-compile(export_all). 
generate_exception(1) -> a; 
generate_exception(2) -> throw(a); 
generate_exception(3) -> exit(a); 
generate_exception(4) -> {'EXIT', a}; 
generate_exception(5) -> erlang:error(a). 
demo1() -> 
   [catcher(I) || I <- [1,2,3,4,5]]. 
catcher(N) -> 
   try generate_exception(N) of 
      Val -> {N, normal, Val} 
   التقاطع 
      throw:X -> {N, caught, thrown, X}; 
      خروج:X -> {N،مأخوذ،خارج،X}; 
      خطأ:X -> {N،مأخوذ،خطأ،X} 
   نهاية. 
      
demo2() -> 
   [{I،(التقاطع توليد استثناء(I))} || I <- [1,2,3,4,5]]. 
demo3() -> 
   المحاولة توليد استثناء(5) 
   التقاطع 
      خطأ:X -> 
         {X،erlang:get_stacktrace()} 
   نهاية. 
   
البحث(N) -> 
   حالة(N) -> 
      1 -> {'EXIT', a}; 
      2 -> خروج(a) 
   نهاية.

إذا قمنا بتشغيل برنامج HelloWorld:demo().، سنحصل على النتيجة التالية

[{1،طبيعي،a},
{2،مأخوذ،مطروح،a},
{3،مأخوذ،خارج،a},
{4،طبيعي،{'EXIT',a}},
{5,مأخوذ،خطأ،a}]