A Go-ban a struct olyan nevesített elemek sorozata, amelyeket mezőknek nevezünk; minden mezőnek van neve és típusa.
Egy mező nevének egyedinek kell lennie a structon belül.
A structok az objektumorientált programozási paradigma osztályaihoz hasonlíthatók.
Új structot a type és a struct kulcsszóval hozol létre, majd a mezők nevét és típusát explicit módon adod meg.
Például itt definiáljuk a Shape structot, amely egy alakzat nevét és méretét tárolja:
type Shape struct {
name string
size int
}
A structokban a mezőnevek a Go konvencióját követik: a kisbetűvel kezdődő nevű mezők csak az ugyanabban a csomagban lévő kód számára láthatók, míg a nagybetűvel kezdődők más csomagokból is láthatók.
Miután definiáltad a structot, létre kell hoznod egy új példányt, amelyben a mezőket a nevükkel adod meg, tetszőleges sorrendben:
s := Shape {
name: "Square",
size: 25,
}
A példány mezőinek olvasásához vagy módosításához a . jelölést használd:
// Update the name and the size
s.name = "Circle"
s.size = 35
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 35
A mezők, amelyekhez nem rendeltél kezdőértéket, a nullaértéküket kapják. Például:
s := Shape{name: "Circle"}
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 0
Létrehozhatsz egy struct példányt a mezőnevek használata nélkül is, amennyiben a mezőket sorrendben adod meg:
s := Shape {
"Oval",
20,
}
Ez a szintaxis azonban törékeny kódnak számít, mert eltörhet, amikor új mező kerül a structba, különösen akkor, ha az új mező típusa más.
A következő példában egy plusz mezőt adunk a Shape structhoz:
type Shape struct {
name string
description string // new field 'description' added
size int
}
s := Shape{
"Circle",
20,
}
// Since the second field of the struct is now a string and not an int,
// the compiler will throw an error when compiling the program:
// Output: cannot use 20 (type untyped int) as type string in field value
// Output: too few values in Shape{...}
Néha jó, ha vannak olyan függvényeink, amelyek segítenek structpéldányokat létrehozni.
A konvenció szerint ezeket a függvényeket általában New-nak hívják, vagy a nevük New-val kezdődik, de mivel egyszerű függvényekről van szó, bármilyen nevet adhatsz nekik.
Más nyelvek konstruktorai juthatnak róluk eszedbe, de a Go-ban ezek is csak egyszerű függvények.
A következő példában az egyik ilyen New függvényt használjuk arra, hogy létrehozzunk egy új Shape példányt, és automatikusan beállítsuk az alakzat size mezőjének alapértelmezett értékét:
func NewShape(name string) Shape {
return Shape{
name: name,
size: 100, //default-value for size is 100
}
}
NewShape("Triangle")
// => Shape { name: "Triangle", size: 100 }
A New függvények használatának a következő előnyei lehetnek:
New függvényeket gyakran ugyanabban a csomagban deklarálják, mint az általuk inicializált structokat, még a struct privát mezőit is inicializálhatjákEbben a feladatban különböző típusú távirányítós autók közötti versenyeket fogsz szervezni. Minden autónak megvan a maga sebessége és akkumulátorfogyasztási jellemzője.
Az autók teljesen feltöltött (100%-os) akkumulátorral indulnak. Valahányszor vezetsz egy autót a távirányítóval, az megteszi az autó sebességét méterben, és az akkumulátorfogyasztás mértékével csökkenti a hátralévő akkumulátorszázalékot.
Ha egy autó akkumulátora az akkumulátorfogyasztás százaléka alá esik, nem tudod tovább vezetni az autót.
Minden versenypályának megvan a maga hossza. Az autókat úgy tesztelik, hogy ki tudják-e futni a pályát anélkül, hogy kimerülne az akkumulátoruk.
Definiálj egy Car struktúrát a következő int típusú mezőkkel:
Hozz létre távirányítós autót egy NewCar függvény definiálásával, amely a két paramétereként az autó sebességét méterben
és az akkumulátorfogyasztás százalékát veszi át (mindkettő int típusú), majd visszaad egy Car példányt:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
// => Car{speed: 5, batteryDrain: 2, battery:100, distance: 0}
Definiálj egy másik struktúratípust Track néven, amelynek distance mezője egész típusú.
Hozz létre versenypályát egy NewTrack függvény definiálásával, amely egyetlen paramétereként a pálya hosszát veszi át méterben (int típusú):
distance := 800
track := NewTrack(distance)
// => Track{distance: 800}
Valósítsd meg a Drive függvényt, amely az autó sebessége alapján frissíti a megtett méterek számát, és az akkumulátorfogyasztásnak megfelelően csökkenti az akkumulátort.
Ha nincs elég akkumulátor még egy vezetéshez, az autó nem mozdul:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car = Drive(car)
// => Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}
Egy verseny kifutásához az autónak képesnek kell lennie megtenni a verseny távját.
Ez azt jelenti, hogy nem merül ki az akkumulátora, mielőtt átlépi a célvonalat.
Valósítsd meg a CanFinish függvényt, amely paramétereként egy Car és egy Track példányt vesz át, és true-t ad vissza, ha az autó ki tudja futni a versenyt; egyébként false-t ad vissza.
Tételezd fel, hogy éppen a verseny rajtvonalánál állsz, és beindítod az autó motorját a versenyhez. Vedd figyelembe, hogy az autó akkumulátora nem feltétlenül van teljesen feltöltve, amikor a verseny elkezdődik:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
distance := 100
track := NewTrack(distance)
CanFinish(car, track)
// => true
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Go nyelvet 34 fogalom165 feladat segítségével, valódi emberi mentorálással, mindez ingyen.