Erlang 21 - 8. Expressions

8 भाव




erlang

8 भाव

इस खंड में, सभी मान्य Erlang अभिव्यक्तियों को सूचीबद्ध किया गया है। Erlang प्रोग्राम लिखते समय, इसे मैक्रो- और रिकॉर्ड एक्सप्रेशन का उपयोग करने की भी अनुमति है। हालांकि, इन अभिव्यक्तियों को संकलन के दौरान विस्तारित किया जाता है और उस अर्थ में सही नहीं है Erlang अभिव्यक्ति। मैक्रो- और रिकॉर्ड अभिव्यक्ति अलग-अलग वर्गों में शामिल हैं:

8.1 अभिव्यक्ति का मूल्यांकन

जब तक स्पष्ट रूप से अन्यथा नहीं कहा जाता है, तब तक सभी अभिव्यक्तियों का मूल्यांकन एक अभिव्यक्ति से पहले ही किया जाता है। उदाहरण के लिए, अभिव्यक्ति पर विचार करें:

Expr1 + Expr2

Expr1 और Expr2 , जो कि अभिव्यक्ति भी हैं, पहले मूल्यांकन किया जाता है - किसी भी क्रम में - इससे पहले कि प्रदर्शन किया जाता है।

कई ऑपरेटरों को केवल एक निश्चित प्रकार के तर्कों पर लागू किया जा सकता है। उदाहरण के लिए, अंकगणितीय ऑपरेटरों को केवल संख्याओं पर लागू किया जा सकता है। गलत प्रकार का एक तर्क एक badarg रनटाइम त्रुटि का कारण बनता है।

8.2 शर्तें

अभिव्यक्ति का सबसे सरल रूप एक शब्द है, जो एक पूर्णांक, फ्लोट, परमाणु, स्ट्रिंग, सूची, मानचित्र या टुपल है। वापसी मूल्य शब्द ही है।

8.3 चर

एक चर एक अभिव्यक्ति है। यदि एक चर एक मूल्य के लिए बाध्य है, तो वापसी मूल्य यह मूल्य है। अनबाउंड चर केवल पैटर्न में अनुमत हैं।

चर एक बड़े अक्षर या अंडरस्कोर (_) से शुरू होते हैं। चर में अल्फ़ान्यूमेरिक वर्ण, अंडरस्कोर और @ हो सकते हैं।

उदाहरण:

X
Name1
PhoneNumber
Phone_number
_
_Height

वेरिएबल pattern matching का उपयोग करके मानों के लिए बाध्य हैं। एरलैंग एकल असाइनमेंट का उपयोग करता है, अर्थात, एक चर केवल एक बार बाध्य हो सकता है।

अनाम चर को अंडरस्कोर (_) द्वारा चिह्नित किया जाता है और इसका उपयोग तब किया जा सकता है जब एक चर की आवश्यकता होती है लेकिन इसके मूल्य को अनदेखा किया जा सकता है।

उदाहरण:

[H|_] = [1,2,3]

अंडरस्कोर (_) के साथ शुरू होने वाले चर, उदाहरण के लिए, _Height , सामान्य चर हैं, अनाम नहीं। हालांकि वे संकलक द्वारा इस अर्थ में अनदेखी की जाती हैं कि वे अप्रयुक्त चर के लिए कोई चेतावनी उत्पन्न नहीं करते हैं।

उदाहरण:

निम्नलिखित कोड:

member(_, []) ->
    [].

अधिक पठनीय होने के लिए फिर से लिखा जा सकता है:

member(Elem, []) ->
    [].

यदि कोड को ध्वज के साथ संकलित किया जाता है, तो अप्रयुक्त चर, warn_unused_vars लिए चेतावनी का कारण बनता है। इसके बजाय, कोड को फिर से लिखा जा सकता है:

member(_Elem, []) ->
    [].

ध्यान दें कि चूंकि अंडरस्कोर के साथ शुरू होने वाले चर अनाम नहीं हैं, इसलिए यह मेल खाता है:

{_,_} = {1,2}

लेकिन यह विफल रहता है:

{_N,_N} = {1,2}

एक वैरिएबल का दायरा इसका फंक्शन क्लॉज है। if , case , या अभिव्यक्ति receive शाखा में बंधी चर अभिव्यक्ति के बाहर मूल्य रखने के लिए सभी शाखाओं में बंधी होनी चाहिए। अन्यथा उन्हें अभिव्यक्ति के बाहर 'असुरक्षित' माना जाता है।

try अभिव्यक्ति के लिए चर स्कोपिंग सीमित है ताकि अभिव्यक्ति में बंधे चर हमेशा अभिव्यक्ति के बाहर 'असुरक्षित' हों।

8.4 पैटर्न

एक पैटर्न में एक शब्द के समान संरचना होती है लेकिन इसमें अनबाउंड चर हो सकते हैं।

उदाहरण:

Name1
[H|T]
{error,Reason}

पैटर्न को क्लॉज हेड, case और receive एक्सप्रेशन और मैच एक्सप्रेशन की अनुमति है।

मैच ऑपरेटर = पैटर्न में

यदि Pattern1 और पैटर्न 2 वैध पैटर्न हैं, तो निम्नलिखित भी एक मान्य पैटर्न है:

Pattern1 = Pattern2

जब किसी शब्द के विरुद्ध मिलान किया जाता है, तो Pattern1 और Pattern2 दोनों शब्द का मिलान किया जाता है। इस सुविधा के पीछे का विचार शर्तों के पुनर्निर्माण से बचना है।

उदाहरण:

f({connect,From,To,Number,Options}, To) ->
    Signal = {connect,From,To,Number,Options},
    ...;
f(Signal, To) ->
    ignore.

इसके बजाय के रूप में लिखा जा सकता है

f({connect,_,To,_,_} = Signal, To) ->
    ...;
f(Signal, To) ->
    ignore.

पैटर्न में स्ट्रिंग उपसर्ग

तार मिलान करते समय, निम्नलिखित एक मान्य पैटर्न है:

f("prefix" ++ Str) -> ...

यह समतुल्य चीनी के बराबर है, लेकिन पढ़ने में कठिन है:

f([$p,$r,$e,$f,$i,$x | Str]) -> ...

पैटर्न में अभिव्यक्तियाँ

एक अंकगणितीय अभिव्यक्ति को एक पैटर्न के भीतर इस्तेमाल किया जा सकता है यदि यह निम्नलिखित दो स्थितियों में से दोनों को पूरा करता है:

  • यह केवल संख्यात्मक या बिटवाइज़ ऑपरेटरों का उपयोग करता है।
  • जब इसका अनुपालन किया जाता है तो इसके मूल्य का मूल्यांकन निरंतर तक किया जा सकता है।

उदाहरण:

case {Value, Result} of
    {?THRESHOLD+1, ok} -> ...

8.5 मैच

निम्न मिलान, Expr1 , एक पैटर्न, Expr2 खिलाफ:

Expr1 = Expr2

यदि मिलान सफल होता है, तो पैटर्न में कोई भी अनबाउंड चर बाध्य हो जाता है और Expr2 का मान वापस आ जाता है।

यदि मिलान विफल हो जाता है, तो एक badmatch रन-टाइम त्रुटि उत्पन्न होती है।

उदाहरण:

1> {A, B} = {answer, 42}.
{answer,42}
2> A.
answer
3> {C, D} = [1, 2].
** exception error: no match of right-hand side value [1,2]

8.6 फंक्शन कॉल

ExprF(Expr1,...,ExprN)
ExprM:ExprF(Expr1,...,ExprN)

फ़ंक्शन कॉल के पहले रूप में, ExprM:ExprF(Expr1,...,ExprN) , ExprM और ExprF प्रत्येक में एक परमाणु या एक अभिव्यक्ति होना चाहिए जो एक परमाणु का मूल्यांकन करता है। पूरी तरह से योग्य फ़ंक्शन नाम का उपयोग करके फ़ंक्शन को कहा जाता है। इसे अक्सर दूरस्थ या बाहरी फ़ंक्शन कॉल के रूप में संदर्भित किया जाता है।

उदाहरण:

lists:keysearch(Name, 1, List)

फ़ंक्शन कॉल के दूसरे रूप में, ExprF(Expr1,...,ExprN) , ExprF एक परमाणु होना चाहिए या एक मजेदार का मूल्यांकन करना चाहिए।

यदि ExprF एक परमाणु है, तो फ़ंक्शन को कथित रूप से योग्य फ़ंक्शन नाम का उपयोग करके बुलाया जाता है। यदि ExprF फ़ंक्शन स्थानीय रूप से परिभाषित है, तो इसे कहा जाता है। वैकल्पिक रूप से, यदि ExprF को M मॉड्यूल से स्पष्ट रूप से आयात किया जाता है, तो M:ExprF(Expr1,...,ExprN) कहा जाता है। यदि ExprF को न तो स्थानीय रूप से घोषित किया गया है और न ही आयात किया गया है, तो ExprF को स्वचालित रूप से आयातित BIF का नाम होना चाहिए।

उदाहरण:

handle(Msg, State)
spawn(m, init, [])

उदाहरण जहां ExprF एक मजेदार है:

1> Fun1 = fun(X) -> X+1 end,
Fun1(3).
4
2> fun lists:append/2([1,2], [3,4]).
[1,2,3,4]
3> 

ध्यान दें कि स्थानीय फ़ंक्शन को कॉल करते समय, अंतर्निहित या पूरी तरह से योग्य फ़ंक्शन नाम का उपयोग करने के बीच अंतर होता है। उत्तरार्द्ध हमेशा मॉड्यूल के नवीनतम संस्करण को संदर्भित करता है। Compilation and Code Loading और Function Evaluation

ऑटो-आयातित बीआईएफ के साथ स्थानीय फ़ंक्शन नामकरण

यदि किसी स्थानीय फ़ंक्शन का ऑटो-आयातित BIF के समान नाम है, तो शब्दार्थ यह है कि अनुमानित रूप से योग्य फ़ंक्शन कॉल स्थानीय रूप से परिभाषित फ़ंक्शन को निर्देशित किए जाते हैं, BIF के लिए नहीं। भ्रम से बचने के लिए, एक कंपाइलर निर्देश उपलब्ध है, -compile({no_auto_import,[F/A]}) , जो -compile({no_auto_import,[F/A]}) को ऑटो-आयातित नहीं बनाता है। कुछ स्थितियों में, ऐसा संकलन-निर्देश अनिवार्य है।

चेतावनी

ओटीपी आर 14 ए (ईआरटीएस संस्करण 5.8) से पहले, एक फ़ंक्शन के लिए एक अनुमानित रूप से योग्य फ़ंक्शन कॉल, जिसका नाम ऑटो-आयातित बीआईएफ के समान है, जिसके परिणामस्वरूप बीआईएफ कहा जाता है। संकलक के नए संस्करणों में, स्थानीय फ़ंक्शन को इसके बजाय कहा जाता है। यह इस बात से बचने के लिए है कि ऑटो-आयातित बीआईएफ के सेट में भविष्य के जोड़ पुराने चुपचाप पुराने कोड के व्यवहार को नहीं बदलते हैं।

हालाँकि, उस पुराने (पूर्व R14) कोड से बचने के लिए OTP संस्करण R14A या बाद में संकलित होने पर अपना व्यवहार बदल दिया, निम्नलिखित प्रतिबंध लागू होता है: यदि आप R14A (ERTS संस्करण) से पहले OTP संस्करणों में स्वतः आयात किए गए BIF के नाम को ओवरराइड करते हैं 5.8) और आपके कोड में उस फ़ंक्शन के लिए एक अंतर्निहित योग्य कॉल है, आपको या तो एक संकलक निर्देश का उपयोग करके ऑटो-आयात को स्पष्ट रूप से हटाने की आवश्यकता है, या कॉल को पूरी तरह से योग्य फ़ंक्शन कॉल के साथ बदलें। अन्यथा आपको एक संकलन त्रुटि मिलती है। निम्नलिखित उदाहरण देखें:

-export([length/1,f/1]).

-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported

length([]) ->
    0;
length([H|T]) ->
    1 + length(T). %% Calls the local function length/1

f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
                                  %% which is allowed in guards
    long.

एक ही तर्क अन्य मॉड्यूल से स्पष्ट रूप से आयातित कार्यों पर लागू होता है, स्थानीय रूप से परिभाषित कार्यों के रूप में। इसे दूसरे मॉड्यूल से फ़ंक्शन आयात करने की अनुमति नहीं है और एक ही समय में मॉड्यूल में घोषित फ़ंक्शन है:

-export([f/1]).

-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported

-import(mod,[length/1]).

f(X) when erlang:length(X) > 33 -> %% Calls erlang:length/1,
                                   %% which is allowed in guards

    erlang:length(X);              %% Explicit call to erlang:length in body

f(X) ->
    length(X).                     %% mod:length/1 is called

Erlang / OTP R14A में और उसके बाद स्वतः-आयातित BIF के लिए, स्थानीय फ़ंक्शन या स्पष्ट आयात के साथ नाम को ओवरराइड करने की हमेशा अनुमति है। हालाँकि, अगर -compile({no_auto_import,[F/A]) निर्देश का उपयोग नहीं किया जाता है, तो संकलक एक चेतावनी जारी करता है जब भी फ़ंक्शन को मॉड्यूल में निहित योग्य फ़ंक्शन नाम का उपयोग करके कहा जाता है।

8.7 यदि

if
    GuardSeq1 ->
        Body1;
    ...;
    GuardSeqN ->
        BodyN
end

एक if GuardSeq की शाखाओं को क्रमिक रूप से स्कैन किया जाता है जब तक कि एक गार्ड अनुक्रम GuardSeq जो सच का मूल्यांकन करता है, पाया जाता है। फिर संबंधित Body (',' द्वारा अलग किए गए भावों का क्रम) का मूल्यांकन किया जाता है।

Body का रिटर्न वैल्यू if एक्सप्रेशन का रिटर्न वैल्यू है।

यदि कोई गार्ड अनुक्रम सही के रूप में मूल्यांकित नहीं किया जाता है, तो if_clause रन-टाइम त्रुटि होती है। यदि आवश्यक हो, गार्ड अभिव्यक्ति true अंतिम शाखा में इस्तेमाल किया जा सकता है, क्योंकि गार्ड अनुक्रम हमेशा सच होता है।

उदाहरण:

is_greater_than(X, Y) ->
    if
        X>Y ->
            true;
        true -> % works as an 'else' branch
            false
    end

8.8 प्रकरण

case Expr of
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end

एक्सप्रेशन का मूल्यांकन किया जाता है और पैटर्न Pattern को क्रमिक रूप से परिणाम के विरुद्ध मिलान किया जाता है। यदि एक मैच सफल होता है और वैकल्पिक गार्ड अनुक्रम GuardSeq सच है, तो संबंधित Body का मूल्यांकन किया जाता है।

Body का रिटर्न वैल्यू case एक्सप्रेशन का रिटर्न वैल्यू है।

यदि कोई वास्तविक रक्षक अनुक्रम के साथ कोई मिलान पैटर्न नहीं है, तो एक case_clause रन-टाइम त्रुटि उत्पन्न होती है।

उदाहरण:

is_valid_signal(Signal) ->
    case Signal of
        {signal, _What, _From, _To} ->
            true;
        {signal, _What, _To} ->
            true;
        _Else ->
            false
    end.

8.9 भेजें

Expr1 ! Expr2

Expr2 द्वारा निर्दिष्ट प्रक्रिया को संदेश के रूप में Expr2 का मान भेजता है। Expr2 का मान भी Expr2 का रिटर्न वैल्यू है।

Expr1 को एक पिड, एक पंजीकृत नाम (परमाणु), या एक टपल {Name,Node} मूल्यांकन करना चाहिए। Name एक परमाणु है और Node एक नोड नाम है, एक परमाणु भी है।

  • यदि Expr1 एक नाम का मूल्यांकन करता है, लेकिन यह नाम पंजीकृत नहीं है, तो एक badarg रन-टाइम त्रुटि उत्पन्न होती है।
  • एक पीआईडी ​​को संदेश भेजना कभी भी विफल नहीं होता है, भले ही पीआईडी ​​एक गैर-मौजूदा प्रक्रिया की पहचान करता हो।
  • वितरित संदेश भेजना, अर्थात, यदि Expr1 एक टपल {Name,Node} (या किसी अन्य नोड पर स्थित एक पिड) का मूल्यांकन करता है, तो भी कभी भी विफल नहीं होता है।

8.10 प्राप्त करें

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end

भेजें ऑपरेटर (!) का उपयोग करके प्रक्रिया को भेजे गए संदेश प्राप्त करता है। पैटर्न Pattern मेलबॉक्स में समय के क्रम में पहले संदेश के खिलाफ क्रमिक रूप से मेल खाते हैं, फिर दूसरा, और इसी तरह। यदि एक मैच सफल होता है और वैकल्पिक गार्ड अनुक्रम GuardSeq सच है, तो संबंधित Body का मूल्यांकन किया जाता है। मेल खाने वाला संदेश भस्म हो जाता है, यानी मेलबॉक्स से हटा दिया जाता है, जबकि मेलबॉक्स में कोई अन्य संदेश अपरिवर्तित रहता है।

Body का रिटर्न वैल्यू receive एक्सप्रेशन का रिटर्न वैल्यू है।

receive कभी नहीं receive । निष्पादन अनिश्चित काल तक, अनिश्चित काल तक, एक संदेश आने तक कि पैटर्न में से एक से मेल खाता है और एक सच्चे गार्ड अनुक्रम के साथ होता है।

उदाहरण:

wait_for_onhook() ->
    receive
        onhook ->
            disconnect(),
            idle();
        {connect, B} ->
            B ! {busy, self()},
            wait_for_onhook()
    end.

receive अभिव्यक्ति को टाइमआउट के साथ संवर्धित किया जा सकता है:

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
after
    ExprT ->
        BodyT
end

ExprT एक पूर्णांक का मूल्यांकन करने के लिए है। उच्चतम अनुमत मूल्य 16 # FFFFFFFF है, अर्थात, मान 32 बिट्स में फिट होना चाहिए। receive..after बिल्कुल receive रूप में काम करता है, सिवाय इसके कि अगर कोई मेल संदेश ExprT मिलीसेकंड के भीतर नहीं आया है, तो इसके बजाय BodyT का मूल्यांकन किया जाता है। BodyT का रिटर्न मान फिर प्राप्त का रिटर्न मान बन जाता BodyT बाद अभिव्यक्ति।

उदाहरण:

wait_for_onhook() ->
    receive
        onhook ->
            disconnect(),
            idle();
        {connect, B} ->
            B ! {busy, self()},
            wait_for_onhook()
    after
        60000 ->
            disconnect(),
            error()
    end.

यह प्राप्त करने के लिए कानूनी receive..after भी शाखा के साथ अभिव्यक्ति नहीं:

receive
after
    ExprT ->
        BodyT
end

यह निर्माण किसी भी संदेश का उपभोग नहीं करता है, केवल ExprT मिलीसेकंड के लिए प्रक्रिया में निष्पादन को निलंबित करता है। इसका उपयोग साधारण टाइमर को लागू करने के लिए किया जा सकता है।

उदाहरण:

timer() ->
    spawn(m, timer, [self()]).

timer(Pid) ->
    receive
    after
        5000 ->
            Pid ! timeout
    end.

टाइमआउट मान के लिए दो विशेष मामले हैं:

infinity
यह प्रक्रिया एक मेल संदेश के लिए अनिश्चित काल तक प्रतीक्षा करने के लिए है; यह टाइमआउट का उपयोग नहीं करने के समान है। यह टाइमआउट मानों के लिए उपयोगी हो सकता है जिन्हें रनटाइम पर परिकलित किया जाता है।
0
यदि मेलबॉक्स में कोई मेल संदेश नहीं है, तो टाइमआउट तुरंत होता है।

8.11 टर्म तुलना

Expr1 op Expr2
सेशन विवरण
== के बराबर
/ = बराबर नही है
= < से कम या बराबर
< से कम
> = इससे बड़ा या इसके बराबर
> से अधिक
=: = बिल्कुल बराबर
= / = बिल्कुल बराबर नहीं

सारणी 8.1: शब्द तुलना संचालक।

तर्क विभिन्न डेटा प्रकारों के हो सकते हैं। निम्नलिखित आदेश परिभाषित किया गया है:

number < atom < reference < fun < port < pid < tuple < map < nil < list < bit string

सूचियों की तुलना तत्व द्वारा तत्व से की जाती है। टुपल्स को आकार द्वारा आदेश दिया जाता है, एक ही आकार के दो ट्यूपल को तत्व द्वारा तत्व की तुलना की जाती है।

मानचित्रों को आकार द्वारा आदेश दिया जाता है, समान आकार वाले दो मानचित्रों की तुलना आरोही शब्द क्रम में कुंजियों से की जाती है और फिर कुंजी क्रम में मूल्यों द्वारा की जाती है। मानचित्रों में प्रमुख क्रम पूर्णांक प्रकारों को फ्लोट प्रकारों से कम माना जाता है।

जब एक पूर्णांक को एक फ्लोट से तुलना करते हैं, तो कम परिशुद्धता वाले शब्द को दूसरे शब्द के प्रकार में बदल दिया जाता है, जब तक कि ऑपरेटर =:= या =/= । फ्लोट पूर्णांक से अधिक सटीक होता है जब तक कि फ्लोट के सभी महत्वपूर्ण आंकड़े दशमलव बिंदु के बाईं ओर नहीं होते हैं। यह तब होता है जब फ्लोट +/- 9007199254740992.0 से बड़ा / छोटा होता है। रूपांतरण की रणनीति फ्लोट के आकार के आधार पर बदल दी जाती है क्योंकि अन्यथा बड़ी फ़्लोट और पूर्णांकों की तुलना करने से उनकी परिवर्तनशीलता कम हो जाती है।

शब्द तुलना संचालक अभिव्यक्ति के true , false या false बुलियन मान लौटाते हैं।

उदाहरण:

1> 1==1.0.
true
2> 1=:=1.0.
false
3> 1 > a.
false
4> #{c => 3} > #{a => 1, b => 2}.
false
4> #{a => 1, b => 2} == #{a => 1.0, b => 2.0}.
true

8.12 अंकगणितीय अभिव्यक्तियाँ

op Expr
Expr1 op Expr2
ऑपरेटर विवरण तर्क प्रकार
+ यूनरी + संख्या
- यूनरी - संख्या
+ संख्या
- संख्या
* संख्या
/ फ्लोटिंग पॉइंट डिवीजन संख्या
bnot यूनिक बिटवाइज़ नहीं पूर्णांक
div पूर्णांक विभाजन पूर्णांक
रेम X / Y का पूर्णांक शेष पूर्णांक
बैंड बिटवाइज़ और पूर्णांक
Bor बिटवाइस OR पूर्णांक
bxor अंकगणित बिटकॉइन XOR पूर्णांक
बीएसएल अंकगणित बिटशिफ्ट छोड़ दिया पूर्णांक
बीएसआर बिटशिफ्ट सही पूर्णांक

तालिका 8.2: अंकगणित संचालक।

उदाहरण:

1> +1.
1
2> -1.
-1
3> 1+1.
2
4> 4/2.
2.0
5> 5 div 2.
2
6> 5 rem 2.
1
7> 2#10 band 2#01.
0
8> 2#10 bor 2#01.
3
9> a + 10.
** exception error: an error occurred when evaluating an arithmetic expression
     in operator  +/2
        called as a + 10
10> 1 bsl (1 bsl 64).
** exception error: a system limit has been reached
     in operator  bsl/2
        called as 1 bsl 18446744073709551616

8.13 बूलियन एक्सप्रेशन

op Expr
Expr1 op Expr2
ऑपरेटर विवरण
नहीं एकात्मक तार्किक नहीं
तथा तार्किक और
या तार्किक या
XOR तार्किक XOR

तालिका 8.3: तार्किक संचालक।

उदाहरण:

1> not true.
false
2> true and false.
false
3> true xor false.
true
4> true or garbage.
** exception error: bad argument
     in operator  or/2
        called as true or garbage

8.14 शॉर्ट-सर्किट एक्सप्रेशंस

Expr1 orelse Expr2
Expr1 andalso Expr2

Expr2 का मूल्यांकन केवल यदि आवश्यक हो तो किया जाता है। अर्थात, Expr2 का मूल्यांकन केवल तभी किया जाता है:

  • Expr1 एक orelse अभिव्यक्ति में false मूल्यांकन करता है।

या

  • Expr1 एक Expr1 अभिव्यक्ति में true मूल्यांकन करता true

Expr1 का मान या तो लौटाता है (जो true या false ) या Expr2 का Expr2 (यदि Expr2 का मूल्यांकन किया जाता है)।

उदाहरण 1:

case A >= -1.0 andalso math:sqrt(A+1) > B of

यह तब भी काम करता है, यदि A -1.0 से कम है, क्योंकि उस स्थिति में, math:sqrt/1 का कभी मूल्यांकन नहीं किया जाता है।

उदाहरण 2:

OnlyOne = is_atom(L) orelse
         (is_list(L) andalso length(L) == 1),

Erlang / OTP R13A से, Expr2 को बूलियन मान का मूल्यांकन करने की आवश्यकता नहीं है। एक परिणाम के रूप में, orelse और orelse अब पूंछ-पुनरावर्ती हैं। उदाहरण के लिए, निम्नलिखित कार्य Erlang / OTP R13A और बाद में पूंछ-पुनरावर्ती है:

all(Pred, [Hd|Tail]) ->
    Pred(Hd) andalso all(Pred, Tail);
all(_, []) ->
    true.

8.15 सूची संचालन

Expr1 ++ Expr2
Expr1 -- Expr2

सूची का संघटन संचालक ++ अपने पहले तर्क को उसके दूसरे तर्क में जोड़ता है और परिणामी सूची को लौटाता है।

सूची घटाव ऑपरेटर -- एक सूची का उत्पादन करता है जो पहले तर्क की एक प्रति है। प्रक्रिया निम्नानुसार है: दूसरे तर्क में प्रत्येक तत्व के लिए, इस तत्व की पहली घटना (यदि कोई हो) को हटा दिया जाता है।

उदाहरण:

1> [1,2,3]++[4,5].
[1,2,3,4,5]
2> [1,2,3,2,1,2]--[2,1,2].
[3,1,2]
चेतावनी

A -- B की जटिलता length(A)*length(B) आनुपातिक है। यही है, यह बहुत धीमी हो जाती है अगर A और B दोनों लंबी सूची हैं।

8.16 मैप एक्सप्रेशन

मानचित्र बनाना

एक नए मानचित्र का निर्माण एक अभिव्यक्ति K को दूसरी अभिव्यक्ति V साथ जुड़े रहने देने से होता है:

#{ K => V }

हर एसोसिएशन को सूचीबद्ध करके नए मानचित्र निर्माण में कई संघों को शामिल कर सकते हैं:

#{ K1 => V1, .., Kn => Vn }

एक खाली मानचित्र का निर्माण किसी भी शब्द को एक दूसरे से जोड़कर नहीं किया जाता है:

#{}

मानचित्र की सभी कुंजियाँ और मूल्य शब्द हैं। किसी भी अभिव्यक्ति का पहले मूल्यांकन किया जाता है और फिर परिणामी शब्दों को क्रमशः कुंजी और मूल्य के रूप में उपयोग किया जाता है।

कुंजी और मूल्यों को => तीर द्वारा अलग किया जाता है और संघों को अल्पविराम द्वारा अलग किया जाता है ,

उदाहरण:

M0 = #{},                 % empty map
M1 = #{a => <<"hello">>}, % single association with literals
M2 = #{1 => 2, b => b},   % multiple associations with literals
M3 = #{k => {A,B}},       % single association with variables
M4 = #{{"w", 1} => f()}.  % compound key associated with an evaluated expression

यहां, A और B किसी भी अभिव्यक्ति हैं और M0 M4 माध्यम से M4 M0 परिणामी मानचित्र शर्तें हैं।

यदि दो मिलान कुंजी घोषित की जाती हैं, तो बाद की कुंजी पूर्वता लेती है।

उदाहरण:

1> #{1 => a, 1 => b}.
#{1 => b }
2> #{1.0 => a, 1 => b}.
#{1 => b, 1.0 => a}

वह क्रम जिसमें कुंजियों (और उनसे जुड़े मूल्यों) का निर्माण करने वाले भावों का मूल्यांकन किया जाता है। निर्माण में कुंजी-मूल्य वाले जोड़े का वाक्य-विन्यास क्रम कोई प्रासंगिकता नहीं है, सिवाय दो मिलान कुंजी के हाल ही में उल्लेखित मामले में।

नक्शे को अद्यतन करना

किसी मानचित्र को अपडेट करने पर उसका निर्माण करने के समान सिंटैक्स होता है।

मानचित्र को अद्यतन करने के लिए परिभाषित करने वाली एक अभिव्यक्ति, अभिव्यक्ति को अद्यतन करने के लिए कुंजी को परिभाषित करने और उनके संबंधित मूल्यों के सामने रखी गई है:

M#{ K => V }

यहाँ M एक प्रकार का नक्शा है और K और V कोई भी अभिव्यक्ति है।

यदि कुंजी K मानचित्र में किसी मौजूदा कुंजी से मेल नहीं खाती है, तो कुंजी K से मान V तक एक नया संघ बनाया जाता है।

यदि कुंजी K मानचित्र M में एक मौजूदा कुंजी से मेल खाता है, तो उसका संबद्ध मान नए मान V से बदल दिया जाता है। दोनों मामलों में, मूल्यांकन किया गया मानचित्र अभिव्यक्ति एक नया नक्शा देता है।

यदि M टाइप मैप का नहीं है, तो टाइप badmap का एक अपवाद फेंक दिया जाता है।

केवल एक मौजूदा मूल्य को अपडेट करने के लिए, निम्नलिखित सिंटैक्स का उपयोग किया जाता है:

M#{ K := V } 

यहाँ M एक प्रकार का नक्शा है, V एक अभिव्यक्ति है और K एक अभिव्यक्ति है जो M में मौजूदा कुंजी का मूल्यांकन करता है।

यदि कुंजी K मानचित्र M में किसी भी मौजूदा कुंजी से मेल नहीं खाती है, तो रन टाइम पर टाइप badarg का अपवाद शुरू हो जाता है। यदि एक मिलान कुंजी K मानचित्र M में मौजूद है, तो इसका संबद्ध मान नए मान V से बदल दिया जाता है, और मूल्यांकित मानचित्र अभिव्यक्ति एक नया मानचित्र लौटाती है।

यदि M टाइप मैप का नहीं है, तो टाइप badmap का एक अपवाद फेंक दिया जाता है।

उदाहरण:

M0 = #{},
M1 = M0#{a => 0},
M2 = M1#{a => 1, b => 2},
M3 = M2#{"function" => fun() -> f() end},
M4 = M3#{a := 2, b := 3}.  % 'a' and 'b' was added in `M1` and `M2`.

यहाँ M0 कोई भी नक्शा है। यह निम्नानुसार है कि M1 .. M4 नक्शे भी हैं।

अधिक उदाहरण:

1> M = #{1 => a}.
#{1 => a }
2> M#{1.0 => b}.
#{1 => a, 1.0 => b}.
3> M#{1 := b}.
#{1 => b}
4> M#{1.0 := b}.
** exception error: bad argument

जैसा कि निर्माण में, जिस क्रम में कुंजी और मूल्य के भावों का मूल्यांकन किया जाता है उसे परिभाषित नहीं किया जाता है। अद्यतन में कुंजी-मूल्य जोड़े का वाक्य-विन्यास क्रम बिना किसी प्रासंगिकता के होता है, सिवाय उस मामले के जिसमें दो कुंजियाँ मेल खाती हैं। उस स्थिति में, बाद वाले मूल्य का उपयोग किया जाता है।

पैटर्न में नक्शे

मानचित्रों से कुंजी-मूल्य संघों का मिलान निम्नानुसार किया जाता है:

#{ K := V } = M

यहाँ M कोई भी मानचित्र है। कुंजी K को बाध्य चर या शाब्दिक के साथ एक अभिव्यक्ति होना चाहिए। V किसी भी पैटर्न के साथ बाउंड या अनबाउंड वैरिएबल हो सकता है।

यदि चर V अनबाउंड है, तो यह कुंजी K संबंधित मान के लिए बाध्य हो जाता है, जो कि M में मौजूद होना चाहिए। यदि चर V बाध्य है, तो उसे K से M में संबद्ध मान से मेल खाना चाहिए।

उदाहरण:

1> M = #{"tuple" => {1,2}}.
#{"tuple" => {1,2}}
2> #{"tuple" := {1,B}} = M.
#{"tuple" => {1,2}}
3> B.
2.

यह चर B को पूर्णांक 2 से बांधता है।

इसी तरह, नक्शे से कई मूल्यों का मिलान किया जा सकता है:

#{ K1 := V1, .., Kn := Vn } = M

यहाँ कुंजियाँ K1 .. Kn शाब्दिक या बाध्य चर के साथ किसी भी अभिव्यक्ति हैं। यदि सभी कुंजी मानचित्र M में मौजूद हैं, तो V1 .. Vn में सभी चर V1 .. Vn को उनकी संबंधित कुंजियों के संबद्ध मानों से मिलान किया जाता है।

यदि मिलान की स्थिति पूरी नहीं होती है, तो मैच विफल रहता है, या तो:

  • एक badmatch अपवाद।

    यह है अगर यह उदाहरण के रूप में मैच ऑपरेटर के संदर्भ में प्रयोग किया जाता है।

  • या जिसके परिणामस्वरूप अगले क्लॉज को फंक्शन हेड और केस एक्सप्रेशन में टेस्ट किया जा रहा है।

मानचित्रों में मिलान केवल के लिए अनुमति देता है := संघों के सीमांकक के रूप में।

जिस क्रम में कुंजियों को मिलान में घोषित किया गया है, उसकी कोई प्रासंगिकता नहीं है।

डुप्लिकेट कुंजियों को कुंजी से जुड़े प्रत्येक पैटर्न के मिलान और मिलान की अनुमति है:

#{ K := V1, K := V2 } = M

एक खाली मानचित्र शाब्दिक के खिलाफ एक अभिव्यक्ति का मिलान, इसके प्रकार से मेल खाता है लेकिन कोई चर बाध्य नहीं हैं:

#{} = Expr

यदि एक्सप्रेशन टाइप मैप का है, तो यह अभिव्यक्ति मेल खाता है, अन्यथा यह अपवाद badmatch साथ विफल हो जाता है।

मिलान सिंटैक्स

फ़ंक्शन प्रमुखों में कुंजी के रूप में शाब्दिक मिलान करना:

%% only start if not_started
handle_call(start, From, #{ state := not_started } = S) ->
...
    {reply, ok, S#{ state := start }};

%% only change if started
handle_call(change, From, #{ state := start } = S) ->
...
    {reply, ok, S#{ state := changed }};

गार्ड में मानचित्र

गार्डों में मानचित्रों की अनुमति तब तक दी जाती है जब तक कि सभी उप-प्रलेख वैध गार्ड अभिव्यक्तियाँ हों।

दो गार्ड बीआईएफ नक्शे संभालते हैं:

  • is_map/1 मॉड्यूल में is_map/1 है
  • map_size/1 मॉड्यूल में map_size/1

8.17 बिट सिंटेक्स एक्सप्रेशंस

<<>>
<<E1,...,En>>

प्रत्येक तत्व Ei बिट स्ट्रिंग के एक खंड को निर्दिष्ट करता है। प्रत्येक तत्व Ei एक मूल्य है, इसके बाद एक वैकल्पिक आकार की अभिव्यक्ति और एक वैकल्पिक प्रकार की विशिष्ट सूची है

Ei = Value |
     Value:Size |
     Value/TypeSpecifierList |
     Value:Size/TypeSpecifierList

एक बिट स्ट्रिंग निर्माण में उपयोग किया जाता है, Value एक अभिव्यक्ति है जो एक पूर्णांक, फ्लोट या बिट स्ट्रिंग का मूल्यांकन करना है। यदि अभिव्यक्ति एकल शाब्दिक या परिवर्तनशील नहीं है, तो इसे कोष्ठकों में संलग्न किया जाना है।

थोड़ा स्ट्रिंग मिलान में उपयोग किया जाता है, Value एक चर या पूर्णांक, फ्लोट या स्ट्रिंग होना चाहिए।

ध्यान दें कि, उदाहरण के लिए, स्ट्रिंग स्ट्रिंग शाब्दिक का उपयोग करते हुए <<"abc">> लिए वाक्यविन्यास चीनी है <<$a,$b,$c>>

एक बिट स्ट्रिंग निर्माण में उपयोग किया जाता है, Size एक अभिव्यक्ति है जो एक पूर्णांक का मूल्यांकन करना है।

एक बिट स्ट्रिंग मिलान में उपयोग किया जाता है, Size एक पूर्णांक, या एक पूर्णांक के लिए बाध्य चर होना चाहिए।

Size का मान इकाइयों में खंड का Size निर्दिष्ट करता है (नीचे देखें)। डिफ़ॉल्ट मान प्रकार पर निर्भर करता है (नीचे देखें):

  • integer यह 8 है।
  • float यह 64 है।
  • binary और bitstring यह पूरी बाइनरी या बिट स्ट्रिंग है।

मिलान में, यह डिफ़ॉल्ट मान केवल अंतिम तत्व के लिए मान्य है। मिलान में अन्य सभी बिट स्ट्रिंग या बाइनरी तत्वों का आकार विनिर्देश होना चाहिए।

utf16 , utf16 और utf32 प्रकारों के लिए, Size नहीं दिया जाना चाहिए। सेगमेंट का आकार स्पष्ट रूप से प्रकार और मूल्य से निर्धारित होता है।

TypeSpecifierList किसी भी क्रम में, हाइफ़न (-) द्वारा अलग किए गए प्रकार के विनिर्देशक की एक सूची है। डिफ़ॉल्ट मान किसी भी प्रकार के लोप किए गए प्रकारों के लिए उपयोग किए जाते हैं।

Type = integer | float | binary | bytes | bitstring | bits | utf8 | utf16 | utf32
डिफ़ॉल्ट integer bytes binary लिए एक शॉर्टहैंड है और bits bitstring लिए bitstring utf प्रकारों के बारे में अधिक जानकारी के लिए नीचे देखें।
signed = signed | unsigned
केवल मिलान के लिए मायने रखता है और जब प्रकार integer । डिफ़ॉल्ट unsigned
Endianness = big | little | native
नेटिव-एंडियन का मतलब है कि एंडियननेस को लोड-टाइम पर हल किया जाता है या तो बड़े-एंडियन या छोटे-एंडियन होते हैं, जो कि सीपीयू के लिए मूल है कि एर्लांग मशीन को चलाया जाता है। एंडियननेस केवल तभी मायने रखता है जब टाइप या तो integer , utf16 , utf32 , या float । डिफ़ॉल्ट big
Unit = unit:IntegerLiteral
अनुमत सीमा 1..256 है। integer , float , और bitstring , और binary लिए 8 के लिए डिफ़ॉल्ट। utf16 , utf32 और utf32 लिए कोई भी यूनिट utf16 नहीं दिया जाना चाहिए।

इकाई के साथ गुणा किए गए Size का मान बिट की संख्या देता है। एक प्रकार के binary में एक आकार होना चाहिए जो समान रूप से 8 से विभाज्य हो।

ध्यान दें

बायनेरिज़ का निर्माण करते समय, यदि पूर्णांक खंड के आकार N में दिए गए पूर्णांक को शामिल करने के लिए बहुत छोटा है, तो पूर्णांक के सबसे महत्वपूर्ण बिट्स को चुपचाप त्याग दिया जाता है और केवल N कम से कम महत्वपूर्ण बिट्स को बाइनरी में डाल दिया जाता है।

प्रकार utf8 , utf16 और utf32 यूनिकोड ट्रांसफॉर्मेशन फॉर्मेट UTF-8, UTF-16 और UTF-32 की एन्कोडिंग / डिकोडिंग को निर्दिष्ट करता है।

जब एक utf प्रकार के सेगमेंट का निर्माण किया जाता है, तो Value ०.१.६ # D7FF या १६ # E000 .... १६ # १० एफएफएफ श्रेणी में पूर्णांक होना चाहिए। यदि Value अनुमत सीमाओं के बाहर है, तो निर्माण एक badarg अपवाद के साथ विफल रहता है। परिणामी बाइनरी सेगमेंट का आकार प्रकार या Value , या दोनों पर निर्भर करता है:

  • utf8 , Value 1-4 बाइट्स में एन्कोडेड है।
  • utf16 , Value 2 या 4 बाइट्स में एन्कोडेड है।
  • utf32 , Value को हमेशा 4 बाइट्स में एन्कोड किया जाता है।

निर्माण करते समय, यूटीएफ प्रकारों में से एक के बाद एक शाब्दिक स्ट्रिंग दिया जा सकता है, उदाहरण के लिए: <<"abc"/utf8>> जो कि के लिए सिंथेटिक चीनी है <<$a/utf8,$b/utf8,$c/utf8>>

एक utf प्रकार के एक सेगमेंट का सफल मिलान, परिणाम में पूर्णांक 0..16 # D7FF या 16 # E000..16 # 10FFFF होता है। यदि मैच का मूल्य उन श्रेणियों के बाहर आता है तो मैच विफल हो जाता है।

टाइप utf8 का एक खंड बाइनरी में 1-4 बाइट्स से मेल खाता है, अगर मैच की स्थिति में बाइनरी में एक वैध यूटीएफ -8 अनुक्रम होता है। (RFC-3629 या यूनिकोड मानक देखें)

प्रकार utf16 का एक खंड बाइनरी में 2 या 4 बाइट्स से मेल utf16 सकता है। मैच विफल हो जाता है अगर मैच की स्थिति में बाइनरी में यूनिकोड कोड बिंदु के कानूनी UTF-16 एन्कोडिंग नहीं होती है। (RFC-2781 या यूनिकोड मानक देखें।)

प्रकार utf32 का एक खंड बाइनरी में 4 बाइट्स उसी तरह से मेल कर सकता है जैसे कि integer खंड 32 बिट्स से मेल खाता है। यदि परिणामस्वरूप पूर्णांक ऊपर उल्लिखित कानूनी श्रेणियों के बाहर है तो मैच विफल हो जाता है।

उदाहरण:

1> Bin1 = <<1,17,42>>.
<<1,17,42>>
2> Bin2 = <<"abc">>.
<<97,98,99>>
3> Bin3 = <<1,17,42:16>>.
<<1,17,0,42>>
4> <<A,B,C:16>> = <<1,17,42:16>>.
<<1,17,0,42>>
5> C.
42
6> <<D:16,E,F>> = <<1,17,42:16>>.
<<1,17,0,42>>
7> D.
273
8> F.
42
9> <<G,H/binary>> = <<1,17,42:16>>.
<<1,17,0,42>>
10> H.
<<17,0,42>>
11> <<G,H/bitstring>> = <<1,17,42:12>>.
<<1,17,1,10:4>>
12> H.
<<17,1,10:4>>
13> <<1024/utf8>>.
<<208,128>>

ध्यान दें कि बिट स्ट्रिंग पैटर्न नेस्टेड नहीं हो सकते हैं।

यह भी ध्यान दें कि " B=<<1>> " की व्याख्या " B =<<1>> " के रूप में की गई है जो एक वाक्यविन्यास त्रुटि है। सही तरीका यह है कि '=' के बाद एक जगह लिखी जाए: " B= <<1>>

Programming Examples में और उदाहरण दिए गए हैं।

8.18 फन एक्सप्रेशन

fun
    [Name](Pattern11,...,Pattern1N) [when GuardSeq1] ->
              Body1;
    ...;
    [Name](PatternK1,...,PatternKN) [when GuardSeqK] ->
              BodyK
end

एक मजेदार अभिव्यक्ति कीवर्ड की fun साथ शुरू होती fun और कीवर्ड के end साथ समाप्त होती है। उनके बीच एक फंक्शन डिक्लेरेशन होना है, एक regular function declaration समान, सिवाय इसके कि फंक्शन नाम ऑप्शनल है और एक वैरिएबल होना है, यदि कोई हो।

फन हेड में वेरिएबल्स फंक्शन का नाम छाया करता है और फंक्शन एक्सप्रेशन के आसपास फंक्शन क्लॉज में दोनों शैडो वैरिएबल। मौज मस्ती में बंधी चरियां मस्ती शरीर के लिए स्थानीय होती हैं।

अभिव्यक्ति का वापसी मूल्य परिणामी मज़ा है।

उदाहरण:

1> Fun1 = fun (X) -> X+1 end.
#Fun<erl_eval.6.39074546>
2> Fun1(2).
3
3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.
#Fun<erl_eval.6.39074546>
4> Fun2(7).
gt
5> Fun3 = fun Fact(1) -> 1; Fact(X) when X > 1 -> X * Fact(X - 1) end.
#Fun<erl_eval.6.39074546>
6> Fun3(4).
24

निम्नलिखित मजेदार अभिव्यक्तियों की भी अनुमति है:

fun Name/Arity
fun Module:Name/Arity

Name/Arity , Name एक परमाणु है और Arity एक पूर्णांक है। Name/Arity एक मौजूदा स्थानीय फ़ंक्शन निर्दिष्ट होना चाहिए। अभिव्यक्ति के लिए सिंथेटिक चीनी है:

fun (Arg1,...,ArgN) -> Name(Arg1,...,ArgN) end

Module:Name/Arity , Module , और Name परमाणु हैं और Arity एक पूर्णांक है। Erlang / OTP R15 से शुरू होकर, Module , Name और Arity भी चर हो सकते हैं। इस तरह से परिभाषित एक मजेदार मॉड्यूल Module के नवीनतम संस्करण में Arity साथ फ़ंक्शन Name उल्लेख करता है। इस तरह से परिभाषित एक मजेदार मॉड्यूल के लिए कोड पर निर्भर नहीं है जिसमें यह परिभाषित किया गया है।

Programming Examples में और उदाहरण दिए गए हैं।

8.19 कैच एंड थ्रो

catch Expr

मूल्यांकन के दौरान अपवाद न होने तक Expr का मान लौटाता है। उस स्थिति में, अपवाद पकड़ा गया है।

वर्ग error के अपवाद के लिए, अर्थात, रन-टाइम त्रुटियां, {'EXIT',{Reason,Stack}} को लौटा दिया जाता है।

वर्ग से exit के अपवादों के लिए, अर्थात, exit(Term) नामक कोड, {'EXIT',Term} वापस आ गया है।

वर्ग throw के अपवादों के लिए, यह कोड है जिसे throw(Term) कहा जाता है, Term लौटाया जाता है।

Reason त्रुटि के प्रकार पर निर्भर करता है, और Stack हाल ही के फ़ंक्शन कॉल का Stack है, Exit Reasons देखें।

उदाहरण:

1> catch 1+2.
3
2> catch 1+a.
{'EXIT',{badarith,[...]}}

ध्यान दें कि catch की पूर्वता कम होती है और सबएक्सप्रेस को पकड़ने के लिए अक्सर एक ब्लॉक एक्सप्रेशन या कोष्ठक में संलग्न करने की आवश्यकता होती है:

3> A = catch 1+2.
** 1: syntax error before: 'catch' **
4> A = (catch 1+2).
3

बीआईएफ throw(Any) का उपयोग किसी फ़ंक्शन से गैर-स्थानीय रिटर्न के लिए किया जा सकता है। इसका मूल्यांकन एक catch भीतर किया जाना चाहिए, जो Any मूल्य को लौटाता है।

उदाहरण:

5> catch throw(hello).
hello

यदि throw/1 को कैच के भीतर मूल्यांकन नहीं किया जाता है, तो एक nocatch रन-टाइम त्रुटि उत्पन्न होती है।

8.20 ट्राय करें

try Exprs
catch
    Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->
        ExceptionBody1;
    ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->
        ExceptionBodyN
end

यह catch बढ़ाने का काम है। यह संभावना देता है:

  • विभिन्न अपवाद वर्गों के बीच भेद।
  • केवल वांछित लोगों को संभालने के लिए चुनें।
  • अन्य लोगों को एक एन्क्लोज़िंग try या catch , या डिफ़ॉल्ट त्रुटि हैंडलिंग में पास करना।

ध्यान दें कि हालाँकि कीवर्ड catch का प्रयोग एक्सप्रेशन में किया गया है, लेकिन catch एप्रेशन में catch एक्सप्रेशन नहीं है।

यह मूल्यांकन के दौरान अपवाद न होने तक Exprs ( Exprs एक क्रम Expr1, ..., ExprN ) का मान लौटाता है। उस स्थिति में अपवाद पकड़ा गया है और पैटर्न ExceptionPattern सही अपवाद वर्ग के साथ Class क्रमिक रूप से पकड़े गए अपवाद के साथ मेल खाते हैं। यदि कोई मैच सफल होता है और वैकल्पिक गार्ड अनुक्रम ExceptionGuardSeq सही है, तो संबंधित ExceptionBody का मूल्यांकन रिटर्न मान बनने के लिए किया जाता है।

Stacktrace , यदि निर्दिष्ट किया गया है, तो एक चर (पैटर्न नहीं) का नाम होना चाहिए। स्टैक ट्रेस चर के लिए बाध्य होता है जब संबंधित ExceptionPattern मेल खाता है।

यदि Exprs मूल्यांकन के दौरान एक अपवाद होता है, लेकिन सही गार्ड अनुक्रम के साथ दाएं Class का कोई ExceptionPattern नहीं है, अपवाद इस तरह से पारित किया गया है जैसे Exprs को एक try अभिव्यक्ति में संलग्न नहीं किया गया था।

यदि अपवाद अपवाद के मूल्यांकन के दौरान अपवाद होता है, तो उसे पकड़ा नहीं जाता है।

इसे Class और Stacktrace को छोड़ने की अनुमति है। एक छोड़ा गया Class throw लिए आशुलिपि है:

try Exprs
catch
    ExceptionPattern1 [when ExceptionGuardSeq1] ->
        ExceptionBody1;
    ExceptionPatternN [when ExceptionGuardSeqN] ->
        ExceptionBodyN
end

try अभिव्यक्ति में एक अनुभाग हो सकता है:

try Exprs of
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
catch
    Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->
        ExceptionBody1;
    ...;
    ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->
        ExceptionBodyN
end

यदि Exprs का मूल्यांकन बिना किसी अपवाद के सफल होता है, तो पैटर्न Pattern को case एक्सप्रेशन के समान ही परिणाम के विरुद्ध क्रमिक रूप से मिलान किया जाता है, सिवाय इसके कि यदि मिलान विफल हो जाता है, तो try_clause रन-टाइम त्रुटि उत्पन्न होती है।

Body के मूल्यांकन के दौरान होने वाला अपवाद नहीं पकड़ा गया है।

try अभिव्यक्ति को एक सेक्शन के after भी बढ़ाया जा सकता है, जिसका उपयोग साइड इफेक्ट्स के लिए सफाई के लिए किया जा सकता है:

try Exprs of
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
catch
    Class1:ExceptionPattern1[:Stacktrace] [when ExceptionGuardSeq1] ->
        ExceptionBody1;
    ...;
    ClassN:ExceptionPatternN[:Stacktrace] [when ExceptionGuardSeqN] ->
        ExceptionBodyN
after
    AfterBody
end

AfterBody का मूल्यांकन या तो Body या ExceptionBody बाद किया जाता है, चाहे कोई भी हो। AfterBody का मूल्यांकन मूल्य खो गया है; try अभिव्यक्ति का वापसी मूल्य बिना के after अनुभाग के साथ ही है।

भले ही Body या ExceptionBody मूल्यांकन के दौरान कोई अपवाद होता है, AfterBody का मूल्यांकन किया जाता है। इस मामले में अपवाद का मूल्यांकन AfterBody मूल्यांकन के बाद किया जाता है, इसलिए try अभिव्यक्ति से अपवाद बिना किसी खंड के after खंड के साथ समान है।

यदि AfterBody स्वयं के मूल्यांकन के दौरान कोई अपवाद होता है, तो उसे पकड़ा नहीं जाता है। तो अगर AfterBody में एक अपवाद के बाद मूल्यांकन किया जाता है Exprs , Body या ExceptionBody , कि अपवाद खो दिया है और में अपवाद के नीचे दब गया है AfterBody

जब तक of , कम से कम या एक सेक्शन है , तब तक catch , और after सेक्शन सभी वैकल्पिक हैं । तो निम्नलिखित मान्य अभिव्यक्ति हैं: catch after try

try Exprs of 
    Pattern when GuardSeq -> 
        Body 
after 
    AfterBody 
end

try Exprs
catch 
    ExpressionPattern -> 
        ExpressionBody
after
    AfterBody
end

try Exprs after AfterBody end

अगला उपयोग करने का एक उदाहरण है after । यह फ़ाइल को बंद कर देता है, यहां तक ​​कि अपवादों की स्थिति में file:read/2 या अंदर भी binary_to_term/1 । अपवाद के बिना के रूप में ही कर रहे हैं try ... after ... end अभिव्यक्ति:

termize_file(Name) ->
    {ok,F} = file:open(Name, [read,binary]),
    try
        {ok,Bin} = file:read(F, 1024*1024),
        binary_to_term(Bin)
    after
        file:close(F)
    end.

अगला try अनुकरण करने के लिए उपयोग करने का एक उदाहरण है catch Expr :

try Expr
catch
    throw:Term -> Term;
    exit:Reason -> {'EXIT',Reason}
    error:Reason:Stk -> {'EXIT',{Reason,Stk}}
end

8.21 कोष्ठक अभिव्यक्तियाँ

(Expr)

कोष्ठक अभिव्यक्तियाँ ओवरराइड करने के लिए उपयोगी हैं operator precedences , उदाहरण के लिए, अंकगणितीय अभिव्यक्तियों में:

1> 1 + 2 * 3.
7
2> (1 + 2) * 3.
9

8.22 ब्लॉक एक्सप्रेस

begin
   Expr1,
   ...,
   ExprN
end

ब्लॉक एक्ट्रेसेस एक क्लॉज बॉडी की तरह ही एक्सप्रेशन के सीक्वेंस को ग्रुप करने का तरीका प्रदान करती हैं। वापसी मूल्य अंतिम अभिव्यक्ति का मूल्य है ExprN

8.23 सूची बोध

सूची की समझ कई आधुनिक कार्यात्मक प्रोग्रामिंग भाषाओं की एक विशेषता है। कुछ नियमों के अधीन, वे एक सूची में तत्वों को उत्पन्न करने के लिए एक रसीला अंकन प्रदान करते हैं।

सूची समझ Zermelo-Frankel सेट सिद्धांत में समझ स्थापित करने के लिए अनुरूप हैं और मिरांडा में ZF अभिव्यक्ति कहा जाता है। वे प्रोलॉग के अनुरूप हैं setof और findall प्रोलोगेट में भविष्यवाणी करते हैं।

सूची की समझ निम्नलिखित सिंटैक्स के साथ लिखी गई है:

[Expr || Qualifier1,...,QualifierN]

यहां, Expr एक मनमाना अभिव्यक्ति है, और प्रत्येक Qualifier या तो एक जनरेटर या एक फिल्टर है।

  • एक जनरेटर के रूप में लिखा है
    Pattern <- ListExpr :।
    ListExpr एक अभिव्यक्ति होनी चाहिए, जो शब्दों की सूची का मूल्यांकन करती है।
  • एक बिट स्ट्रिंग जनरेटर के रूप में लिखा है
    BitstringPattern <= BitStringExpr :।
    BitStringExpr एक अभिव्यक्ति होना चाहिए, जो एक बिटस्ट्रिंग का मूल्यांकन करता है।
  • एक फिल्टर एक अभिव्यक्ति है, जो मूल्यांकन करता है true या false

जनरेटर पैटर्न में चर, समारोह खंड में छाया चर, सूची समझ के आसपास।

एक सूची बोधक एक सूची देता है, जहां तत्व Expr जनरेटर सूची तत्वों और बिट स्ट्रिंग जनरेटर तत्वों के प्रत्येक संयोजन के लिए मूल्यांकन करने का परिणाम है , जिसके लिए सभी फ़िल्टर सही हैं।

उदाहरण:

1> [X*2 || X <- [1,2,3]].
[2,4,6]

जब कोई जनरेटर या बिट स्ट्रिंग जनरेटर नहीं होते हैं, तो एक सूची समझ या तो एक तत्व के साथ एक सूची देता है (मूल्यांकन करने का परिणाम Expr ) यदि सभी फ़िल्टर सही हैं या एक खाली सूची अन्यथा

उदाहरण:

1> [2 || is_integer(2)].
[2]
2> [x || is_integer(x)].
[]

में और उदाहरण दिए गए हैं Programming Examples.

8.24 बिट स्ट्रिंग की समझ

बिट स्ट्रिंग समझ सूची बोध के अनुरूप हैं। वे कुशलतापूर्वक और संक्षिप्त रूप से बिट स्ट्रिंग्स उत्पन्न करने के लिए उपयोग किए जाते हैं।

बिट स्ट्रिंग समझ निम्नलिखित सिंटैक्स के साथ लिखी जाती है:

<< BitStringExpr || Qualifier1,...,QualifierN >>

BitStringExpr एक अभिव्यक्ति है जो एक बिट स्ट्रिंग के लिए विकसित होती है। यदि BitStringExpr कोई फ़ंक्शन कॉल है, तो इसे कोष्ठकों में संलग्न किया जाना चाहिए। प्रत्येक Qualifier या तो एक जनरेटर, एक बिट स्ट्रिंग जनरेटर या एक फिल्टर है।

  • एक जनरेटर के रूप में लिखा है
    Pattern <- ListExpr :।
    ListExpr एक अभिव्यक्ति होनी चाहिए जो शब्दों की सूची का मूल्यांकन करती है।
  • एक बिट स्ट्रिंग जनरेटर के रूप में लिखा है
    BitstringPattern <= BitStringExpr :।
    BitStringExpr एक अभिव्यक्ति होनी चाहिए जो बिटस्ट्रिंग का मूल्यांकन करती है।
  • एक फ़िल्टर एक अभिव्यक्ति है जो मूल्यांकन करता है true या false

जनरेटर पैटर्न में चर, फ़ंक्शन खंड में छाया चर, बिट स्ट्रिंग समझ के आसपास।

एक बिट स्ट्रिंग समझ एक बिट स्ट्रिंग देता है, जो BitString बिट स्ट्रिंग जनरेटर तत्वों के प्रत्येक संयोजन के लिए मूल्यांकन के परिणामों को संक्षिप्त करके बनाया जाता है, जिसके लिए सभी फ़िल्टर सही हैं।

उदाहरण:

1> << << (X*2) >> || <<X>> <= << 1,2,3 >> >>.
<<2,4,6>>

में और उदाहरण दिए गए हैं Programming Examples.

8.25 गार्ड अनुक्रम

एक गार्ड अनुक्रम गार्ड का एक अनुक्रम है, जिसे सेमीकोलन (;) द्वारा अलग किया जाता है। गार्ड अनुक्रम सही है अगर कम से कम एक गार्ड सच्चा है। (शेष गार्ड, यदि कोई हो, का मूल्यांकन नहीं किया जाता है।)

Guard1;...;GuardK

एक गार्ड गार्ड अभिव्यक्ति का एक क्रम है, जिसे अल्पविराम (,) द्वारा अलग किया जाता है। यदि सभी गार्ड अभिव्यक्ति का मूल्यांकन करते हैं तो गार्ड सही है true

GuardExpr1,...,GuardExprN

मान्य गार्ड अभिव्यक्तियों का सेट (जिसे कभी-कभी गार्ड परीक्षण भी कहा जाता है) मान्य एरलंग अभिव्यक्तियों के सेट का सबसेट है। वैध अभिव्यक्तियों के सेट को प्रतिबंधित करने का कारण यह है कि गार्ड अभिव्यक्ति के मूल्यांकन को साइड इफेक्ट से मुक्त होने की गारंटी दी जानी चाहिए। मान्य अभिभावक निम्नलिखित हैं:

  • परमाणु true
  • अन्य स्थिरांक (नियम और बाध्य चर), सभी को असत्य माना जाता है
  • तालिका में निर्दिष्ट बीआईएफ को कॉल करता है Type Test BIFs
  • शब्द तुलना
  • अंकगणित के भाव
  • बूलियन अभिव्यक्ति
  • शॉर्ट-सर्किट एक्सप्रेशन ( andalso / orelse )
is_atom/1
is_binary/1
is_bitstring/1
is_boolean/1
is_float/1
is_function/1
is_function/2
is_integer/1
is_list/1
is_map/1
is_number/1
is_pid/1
is_port/1
is_record/2
is_record/3
is_reference/1
is_tuple/1

तालिका 8.4: टेस्ट बीआईएफ टाइप करें

ध्यान दें कि अधिकांश प्रकार के परीक्षण बीआईएफ में is_ उपसर्ग के बिना पुराने समकक्ष हैं । ये पुराने बीआईएफ केवल पीछे की संगतता के लिए बनाए रखे जाते हैं और नए कोड में उपयोग नहीं किए जाते हैं। उन्हें केवल शीर्ष स्तर पर भी अनुमति है। उदाहरण के लिए, उन्हें गार्ड में बूलियन अभिव्यक्तियों की अनुमति नहीं है।

abs(Number)
bit_size(Bitstring)
byte_size(Bitstring)
element(N, Tuple)
float(Term)
hd(List)
length(List)
map_size(Map)
node()
node(Pid|Ref|Port)
round(Number)
self()
size(Tuple|Bitstring)
tl(List)
trunc(Number)
tuple_size(Tuple)

तालिका 8.5: अन्य बीआईएफ गार्ड अभिव्यक्तियों में अनुमति दी

यदि एक अंकगणितीय अभिव्यक्ति, एक बूलियन अभिव्यक्ति, एक शॉर्ट-सर्किट अभिव्यक्ति, या गार्ड बीआईएफ के लिए एक कॉल विफल (अमान्य तर्कों के कारण), तो पूरा गार्ड विफल हो जाता है। यदि गार्ड एक गार्ड अनुक्रम का हिस्सा था, तो अनुक्रम में अगले गार्ड (यानी, अगले अर्धविराम के बाद गार्ड) का मूल्यांकन किया जाता है।

8.26 संचालक वरीयता

गिरने की प्राथमिकता में ऑपरेटर की प्राथमिकता:

:
#
Unary + - नहीं नहीं
/ * div rem band और छोड़ दिया साहचर्य
+ - bor bxor bsl bsr या xor छोड़ दिया साहचर्य
++ - सही सहयोगी
== / = = <<> => =: = = / =
और भी
वरना
=! सही सहयोगी
पकड़

तालिका 8.6: संचालक प्राथमिकता

किसी अभिव्यक्ति का मूल्यांकन करते समय, सर्वोच्च प्राथमिकता वाले ऑपरेटर का मूल्यांकन पहले किया जाता है। समान प्राथमिकता वाले ऑपरेटरों का मूल्यांकन उनकी सहानुभूति के अनुसार किया जाता है।

उदाहरण:

बाएं सहयोगी अंकगणितीय संचालकों का मूल्यांकन बाएं से दाएं किया जाता है:

6 + 5 * 4 - 3 / 2 evaluates to
6 + 20 - 1.5 evaluates to
26 - 1.5 evaluates to
24.5

Original text