A structok a map-ekre épülő kiterjesztések, amelyek fordítási idejű ellenőrzéseket és alapértelmezett értékeket biztosítanak. A struct arról a modulról kapja a nevét, amelyben definiálva van. Struct definiálásához használd a defstruct konstrukciót. A konstrukció általában közvetlenül a moduldefiníció után következik. A defstruct elfogad vagy atomok listáját (a nil alapértelmezett értékekhez) vagy kulcsszólistát (a megadott alapértelmezett értékekhez). Az alapértelmezett érték nélküli mezőknek meg kell előzniük az alapértelmezett értékkel rendelkezőket.
defmodule Plane do
defstruct [:engine, wings: 2]
end
plane = %Plane{}
# => %Plane{engine: nil, wings: 2}
Mivel a structok map-ekre épülnek, a legtöbb map-függvényt használhatjuk értékek lekérésére és módosítására. A structoknál az Access Behaviour nincs implementálva. A structmezők eléréséhez helyette a statikus elérési operátor . használata javasolt.
mezőértékek lekérése:
plane = %Plane{}
plane.engine
# => nil
Map.fetch(plane, :wings)
# => {:ok, 2}
mezőértékek frissítése
plane = %Plane{}
%{plane | wings: 4}
# => %Plane{engine: nil, wings: 4}
A structok használhatók mintailesztésben a struct nevével vagy anélkül is.
plane = %Plane{}
%Plane{wings: wings} = plane
%{wings: wings} = plane
Ha a mintába belefoglalod a struct nevét, biztosíthatod, hogy a bal és a jobb oldal is ugyanolyan típusú struct legyen.
defmodule Helicopter do
defstruct [:engine, rotors: 1]
end
%Plane{} = %Helicopter{}
# => (MatchError) no match of right hand side value: %Helicopter{engine: nil, rotors: 1}
A @enforce_keys modulattribútumot használhatjuk a mezőkulcsok listájával annak biztosítására, hogy az értékek inicializálva legyenek a struct létrehozásakor. Ha egy kulcs nincs a listában, az értéke nil lesz, mint a fenti példában. Ha egy kikényszerített kulcs nincs inicializálva, hiba keletkezik.
defmodule User do
@enforce_keys [:username]
defstruct [:username]
end
%User{}
# => (ArgumentError) the following keys must also be given when building struct User: [:username]
Ebben a feladatban egy távirányítós autóval fogsz játszani, amelyre végre összegyűjtöttél elég pénzt, hogy megvedd.
Az autók teljes (100%-os) akkumulátorral indulnak. Valahányszor a távirányítóval vezeted az autót, 20 métert tesz meg, és az akkumulátor egy százalékát meríti. Az autó beceneve csak a létrehozásakor derül ki.
A távirányítós autón van egy menő LED-kijelző, amely két információt mutat:
"<METERS> meters"."Battery at <PERCENTAGE>%".Ha az akkumulátor 0%-on van, nem tudod tovább vezetni az autót, és az akkumulátorkijelző a "Battery empty" szöveget fogja mutatni.
Valósítsd meg a RemoteControlCar.new/0 függvényt, amely egy vadonatúj, távirányítós autót reprezentáló struktúrát ad vissza:
RemoteControlCar.new()
# => %RemoteControlCar{
# battery_percentage: 100,
# distance_driven_in_meters: 0,
# nickname: "none"
# }
A becenév kötelező a struktúrában, ezért gondoskodj róla, hogy az érték a new függvényben kapjon kezdőértéket, ne pedig a struktúrában.
Valósítsd meg a RemoteControlCar.new/1 függvényt, amely egy vadonatúj távirányítós autó struktúrát ad vissza a megadott becenévvel:
RemoteControlCar.new("Blue")
# => %RemoteControlCar{
# battery_percentage: 100,
# distance_driven_in_meters: 0,
# nickname: "Blue"
# }
Valósítsd meg a RemoteControlCar.display_distance/1 függvényt, amely a LED-kijelzőn megjelenített távolságot adja vissza:
car = RemoteControlCar.new()
RemoteControlCar.display_distance(car)
# => "0 meters"
Ügyelj rá, hogy a függvény argumentumként csak RemoteControlCar struktúrát fogadjon el.
Valósítsd meg a RemoteControlCar.display_battery/1 függvényt, amely a LED-kijelzőn megjelenített akkumulátortöltöttséget adja vissza:
car = RemoteControlCar.new()
RemoteControlCar.display_battery(car)
# => "Battery at 100%"
Ügyelj rá, hogy a függvény argumentumként csak RemoteControlCar struktúrát fogadjon el. Ha az akkumulátor 0%-on van, az akkumulátorkijelző „Battery empty” szöveget fog mutatni.
Valósítsd meg a RemoteControlCar.drive/1 függvényt, amely:
RemoteControlCar.new("Red")
|> RemoteControlCar.drive()
# => %RemoteControlCar{
# battery_percentage: 99,
# distance_driven_in_meters: 20,
# nickname: "Red"
# }
Ügyelj rá, hogy a függvény argumentumként csak RemoteControlCar struktúrát fogadjon el.
Módosítsd a RemoteControlCar.drive/1 függvényt úgy, hogy ne növelje a megtett távolságot, és ne csökkentse az akkumulátor töltöttségi százalékát, amikor az akkumulátor lemerült (0%-on van):
%RemoteControlCar{
battery_percentage: 0,
distance_driven_in_meters: 1980,
nickname: "Red"
}
|> RemoteControlCar.drive()
# => %RemoteControlCar{
# battery_percentage: 0,
# distance_driven_in_meters: 1980,
# nickname: "Red"
# }
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Elixir nyelvet 58 fogalom168 feladat segítségével, valódi emberi mentorálással, mindez ingyen.