Skip to the content.

Atom տվյալների տիպը

Atom-ը Elixir-ի ամենապարզ տիպերից է։ Պաշտոնական սահմանումը հետևյալն է. atom-ը հաստատուն է, որի արժեքը իր իսկ անունն է։

Առաջին անգամ կարդալիս այս սահմանումը մի փոքր տարօրինակ է հնչում, ուստի դիտարկենք այն օրինակով։ Atom-ը գրվում է : նշանով, որին հաջորդում է անունը՝

iex(1)> :apple
:apple
iex(2)> :ok
:ok

:apple-ը ո՛չ փոփոխական է, ո՛չ էլ string․ այն կրում է հենց իր արժեքը։

Ծանոթ անալոգիա՝ enum-ներ առանց հայտարարման

Եթե ծանոթ եք Java-ին, C#-ին, կամ նման այլ օբյեկտ կողմնորոշված լեզվի, ապա atom-ները հասկանալու ամենակարճ ճանապարհը enum-ներն են։ Դրանք իհարկե նույն բանը չեն, բայց որպեսզի մոտավորապես պատկերացնենք իմաստն ու հնարավոր կիրառության որոշ դեպքեր, կարելի է համեմատականներ տանել enum-ների հետ։ Java-ում իրարից տարբերվող ֆիքսված արժեքների խումբ նկարագրելու համար նախ պետք է հայտարարել տիպը՝

// Java
enum Status {
    OK,
    ERROR
}

Elixir-ում ոչինչ հայտարարել պետք չէ․ պարզապես գրում եք :ok կամ :error այնտեղ, որտեղ անհրաժեշտ է, և արժեքը սկսում է գոյություն ունենալ՝

:ok
:error
:pending

Կարելի է atom-ները հասկանալ նաև որպես թեթև, ազատ, ցանկացած տեղ ստեղծվող պիտակներ (label)։

Համեմատում

Երկու atom հավասար են միայն այն դեպքում, երբ նրանց անունները նույնն են՝

iex(1)> :apple == :apple
true
iex(2)> :apple == :orange
false

Այստեղ կա մի կարևոր տեխնիկական դետալ, որը atom-ներին տալիս է առավելություն string-ների նկատմամբ։ Երբ համեմատում ենք երկու string, համակարգը ստիպված է դրանք համեմատել նիշ առ նիշ։ Atom-ները, մինչդեռ, BEAM վիրտուալ մեքենայի ներսում պահվում են հատուկ աղյուսակում, և յուրաքանչյուր atom այնտեղ գոյություն ունի միայն մեկ օրինակով։ Երկու atom համեմատելը, հետևաբար, ընդամենը երկու ներքին հասցե համեմատել է՝ ակնթարթային գործողություն՝ անկախ անվան երկարությունից։

Ամենատարածված կիրառությունը՝ գործողության արդյունքի նշում

Elixir կոդում ամենուր կհանդիպեք :ok և :error atom-ներին․ դրանցով ընդունված է նշել արդյոք գործողությունը հաջողվե՞ց, թե՞ ոչ։ Ամենից հաճախ դրանք հանդես են գալիս tuple-ի (այդ տիպին կծանոթանանք առաջիկա հոդվածներից մեկում) առաջին տարրի դերում՝

{:ok, result}
{:error, reason}

Առաջին տարրն ասում է, թե ինչ տեսակի արդյունք է, երկրորդը՝ բուն արժեքը։ Սա Elixir-ի ամենակարևոր ոճային առանձնահատկություններից է, և դրան դեռ շատ ենք անդրադառնալու։

true֊ն, false֊ը և nil-ը նույնպես atom-ներ են

Ի դեպ բուլյան արժեքներ true-ն և false-ը սովորական atom-ներ են, որոնց համար լեզուն թույլ է տալիս :-ը չգրել։ Նույնը վերաբերում է նաև nil-ին («ոչինչ», «գոյություն չունի» արժեքը, մի շարք տարածված ծրագրավորման լեզուների null-ի համարժեքը)՝

iex(1)> true == :true
true
iex(2)> is_atom(false)
true
iex(3)> is_boolean(:false)
true
iex(4)> nil == :nil
true

Այսինքն՝ true գրելը պարզապես :true գրելու կարճ ձևն է։ Գործնականում, իհարկե, միշտ գրում ենք առանց :-ի։

Անվանման կանոնները

Atom-ի անունը կարող է պարունակել տառեր, թվանշաններ, ընդգծման նշան և @ նշան՝

:apple
:user_role
:node@host

Եթե անվան մեջ կա այլ նիշ, օրինակ՝ բացատ, ապա անունը պետք է վերցնել չակերտների մեջ՝

iex(1)> :"this is an atom with spaces"
:"this is an atom with spaces"

Գործնականում չակերտների մեջ ներառված atom-ները հազվադեպ են հանդիպում․ ընդունված ոճը փոքրատառ snake_case անուններն են՝ այնպես ինչպես փոփոխականների դեպքում։

Կարևոր զգուշացում

Atom-ներն ունեն մի կարևոր առանձնահատկություն, որի մասին արժե իմանալ հենց սկզբից․ ստեղծված atom-ը երբեք չի ջնջվում հիշողությունից (չկա Garbage Collection)։ BEAM-ի atom-ների աղյուսակը միայն աճում է և սկզբնապես ունի 1,048,576 սահմանաչափ (կարգավորելի է +t դրոշակով, առավելագույնը 255 նիշ մեկ atom-ի համար)։

Սովորական կոդի համար սա խնդիր չէ․ ծրագրավորողի սահմանած atom-ները սահմանափակ են։ Խնդիր առաջանում է միայն այն դեպքում, երբ դրանք ստեղծվում են դինամիկ կերպով՝ արտաքին մուտքային տվյալներից (օրինակ՝ String.to_atom/1 կամ binary_to_atom/2)։ Աղյուսակը լցվելուն պես BEAM վիրտուալ մեքենան ամբողջությամբ դադարեցնում է աշխատանքը։

Արտաքին մուտքային տվյալներից մի՛ ստեղծեք նոր atom-ներ (պահեք որպես String/Binary) կամ օգտագործեք միայն անվտանգ to_existing_atom տարբերակը։

Atom մոդուլը

Elixir-ի ստանդարտ գրադարանում կա Atom մոդուլը։ Դրա ամենագործածական ֆունկցիաներից մեկը Atom.to_string-ն է, որը atom-ը դարձնում է string՝

iex(1)> Atom.to_string(:apple)
"apple"

Մոդուլն ունի նաև Atom.to_charlist ֆունկցիան․ charlist-երին կանդրադառնանք string-երի մասին հոդվածում։