स्ट्रक्ट, मैप के ऊपर बना एक एक्सटेंशन है, जो कंपाइल-टाइम जाँच और डिफॉल्ट वैल्यू देता है। स्ट्रक्ट का नाम उस मॉड्यूल के नाम पर रखा जाता है जिसमें इसे बनाया जाता है। स्ट्रक्ट बनाने के लिए defstruct कंस्ट्रक्ट का उपयोग कीजिए। यह कंस्ट्रक्ट आमतौर पर मॉड्यूल की परिभाषा के ठीक बाद लिखा जाता है। defstruct या तो एटम का ऐरे लेता है (nil डिफॉल्ट वैल्यू के लिए), या कीवर्ड ऐरे (तय की गई डिफॉल्ट वैल्यू के लिए)। जिन फील्ड की कोई डिफॉल्ट वैल्यू नहीं है, वे डिफॉल्ट वैल्यू वाले फील्ड से पहले आने चाहिए।
defmodule Plane do
defstruct [:engine, wings: 2]
end
plane = %Plane{}
# => %Plane{engine: nil, wings: 2}
चूँकि स्ट्रक्ट मैप के ऊपर बने होते हैं, हम वैल्यू पाने और बदलने के लिए ज़्यादातर मैप फंक्शन इस्तेमाल कर सकते हैं। स्ट्रक्ट के लिए Access Behaviour लागू नहीं होता। इसकी जगह स्ट्रक्ट फील्ड पढ़ने के लिए स्टैटिक एक्सेस ऑपरेटर . इस्तेमाल करना बेहतर है।
फील्ड की वैल्यू पाना:
plane = %Plane{}
plane.engine
# => nil
Map.fetch(plane, :wings)
# => {:ok, 2}
फील्ड की वैल्यू बदलना:
plane = %Plane{}
%{plane | wings: 4}
# => %Plane{engine: nil, wings: 4}
स्ट्रक्ट का पैटर्न मैचिंग में इस्तेमाल स्ट्रक्ट के नाम के साथ या उसके बिना किया जा सकता है।
plane = %Plane{}
%Plane{wings: wings} = plane
%{wings: wings} = plane
पैटर्न में स्ट्रक्ट का नाम शामिल करने से आप यह पक्का कर सकते हैं कि बाईं और दाईं, दोनों तरफ एक ही तरह के स्ट्रक्ट हैं।
defmodule Helicopter do
defstruct [:engine, rotors: 1]
end
%Plane{} = %Helicopter{}
# => (MatchError) no match of right hand side value: %Helicopter{engine: nil, rotors: 1}
स्ट्रक्ट बनाते समय वैल्यू ज़रूर शुरू हो जाएँ, यह पक्का करने के लिए हम फील्ड कीज़ के ऐरे के साथ @enforce_keys मॉड्यूल एट्रिब्यूट इस्तेमाल कर सकते हैं। अगर कोई की सूची में नहीं है, तो उसकी वैल्यू nil होगी, जैसा ऊपर के उदाहरण में दिख रहा है। अगर ज़रूरी बनाई गई कोई की शुरू में नहीं दी गई, तो एरर आती है।
defmodule User do
@enforce_keys [:username]
defstruct [:username]
end
%User{}
# => (ArgumentError) the following keys must also be given when building struct User: [:username]
इस अभ्यास में आप एक रिमोट कंट्रोल कार के साथ खेलेंगे, जिसे खरीदने के लिए आपने अंत में इतना पैसा बचा लिया है।
कार की बैटरी शुरू में पूरी (100%) रहती है। जब भी आप रिमोट कंट्रोल से कार चलाते हैं, वह 20 मीटर तय करती है और बैटरी का एक प्रतिशत खर्च हो जाता है। कार का उपनाम तब तक पता नहीं चलता जब तक कार बन न जाए।
रिमोट कंट्रोल कार पर एक शानदार LED डिस्प्ले लगा है, जो दो तरह की जानकारी दिखाता है:
"<METERS> meters"."Battery at <PERCENTAGE>%".अगर बैटरी 0% पर पहुँच जाए, तो आप कार और नहीं चला सकते, और बैटरी डिस्प्ले पर "Battery empty" दिखाई देगा।
एक बिल्कुल नई रिमोट कंट्रोल कार स्ट्रक्चर लौटाने के लिए RemoteControlCar.new/0 फंक्शन लागू कीजिए:
RemoteControlCar.new()
# => %RemoteControlCar{
# battery_percentage: 100,
# distance_driven_in_meters: 0,
# nickname: "none"
# }
स्ट्रक्चर में उपनाम ज़रूरी है, इसलिए ध्यान रखिए कि वैल्यू new फंक्शन में शुरू में सेट की जाए, स्ट्रक्चर में नहीं।
दिए गए उपनाम के साथ बिल्कुल नई रिमोट कंट्रोल कार स्ट्रक्चर लौटाने के लिए RemoteControlCar.new/1 फंक्शन लागू कीजिए:
RemoteControlCar.new("Blue")
# => %RemoteControlCar{
# battery_percentage: 100,
# distance_driven_in_meters: 0,
# nickname: "Blue"
# }
LED डिस्प्ले पर दिखाई जाने वाली दूरी लौटाने के लिए RemoteControlCar.display_distance/1 फंक्शन लागू कीजिए:
car = RemoteControlCar.new()
RemoteControlCar.display_distance(car)
# => "0 meters"
ध्यान रखिए कि यह फंक्शन आर्गुमेंट के रूप में सिर्फ RemoteControlCar स्ट्रक्चर ही स्वीकार करे।
LED डिस्प्ले पर दिखाया जाने वाला बैटरी प्रतिशत लौटाने के लिए RemoteControlCar.display_battery/1 फंक्शन लागू कीजिए:
car = RemoteControlCar.new()
RemoteControlCar.display_battery(car)
# => "Battery at 100%"
ध्यान रखिए कि यह फंक्शन आर्गुमेंट के रूप में सिर्फ RemoteControlCar स्ट्रक्चर ही स्वीकार करे। अगर बैटरी 0% पर हो, तो बैटरी डिस्प्ले पर "Battery empty" दिखाई देगा।
ऐसा RemoteControlCar.drive/1 फंक्शन लागू कीजिए जो:
RemoteControlCar.new("Red")
|> RemoteControlCar.drive()
# => %RemoteControlCar{
# battery_percentage: 99,
# distance_driven_in_meters: 20,
# nickname: "Red"
# }
ध्यान रखिए कि यह फंक्शन आर्गुमेंट के रूप में सिर्फ RemoteControlCar स्ट्रक्चर ही स्वीकार करे।
RemoteControlCar.drive/1 फंक्शन को ऐसे बदलिए कि जब बैटरी खत्म हो (0% पर हो), तो न तय की गई दूरी बढ़े और न बैटरी प्रतिशत घटे:
%RemoteControlCar{
battery_percentage: 0,
distance_driven_in_meters: 1980,
nickname: "Red"
}
|> RemoteControlCar.drive()
# => %RemoteControlCar{
# battery_percentage: 0,
# distance_driven_in_meters: 1980,
# nickname: "Red"
# }
Exercism पर साइन अप कीजिए और Elixir को 58 कॉन्सेप्ट168 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।