A függvény segítségével kódrészleteket foghatsz össze egy újrahasznosítható egységbe.
A függvény a func kulcsszóból, a függvény nevéből, valamint a kerek zárójelben álló, vesszővel elválasztott listából áll, amely nulla vagy több paramétert és azok típusát tartalmazza.
Minden paraméter típusát kifejezetten meg kell adni, a paramétereknél nincs típuskövetkeztetés. A paramétereknek nincs alapértelmezett értékük, ezért minden függvényparaméter kötelező.
import "fmt"
// No parameters
func PrintHello() {
fmt.Println("Hello")
}
// Two parameters
func PrintGreetingName(greeting string, name string) {
fmt.Println(greeting + " " + name)
}
Az azonos típusú paraméterek együtt is megadhatók, ilyenkor egyetlen típusmegadás követi őket.
import "fmt"
func PrintGreetingName(greeting, name string) {
fmt.Println(greeting + " " + name)
}
Nézzünk meg gyorsan két kifejezést, amelyeket gyakran összekevernek egymással: a parameters és az arguments.
A függvényparaméterek a függvény szignatúrájában megadott nevek, például a greeting és a name a fenti PrintGreetingName függvényben.
A függvényargumentumok azok a konkrét értékek, amelyeket a függvény meghívásakor adunk át a függvény paramétereinek.
Az alábbi példában például a "Hello" és a "Katrina" azok az argumentumok, amelyeket a greeting és a name paraméternek adunk át:
PrintGreetingName("Hello", "Katrina")
A függvényparamétereket nulla vagy több visszatérési érték követi, amelyek típusát szintén kifejezetten meg kell adni.
Az egyetlen visszatérési értéket zárójel nélkül hagyjuk, a többit zárójelbe tesszük.
A függvények a return kulcsszóval adják vissza az értékeket a hívó kódnak.
Egy függvényben több return utasítás is lehet.
A függvény végrehajtása azonnal véget ér, amint elér egy ilyen return utasítást.
Ha egy függvény több értéket ad vissza, azokat vesszővel választjuk el.
func Hello(name string) string {
return "Hello " + name
}
func HelloAndGoodbye(name string) (string, string) {
return "Hello " + name, "Goodbye " + name
}
Egy függvényt úgy hívunk meg, hogy megadjuk a függvény nevét, és zárójelben átadunk egy argumentumot a függvény minden paraméteréhez.
import "fmt"
// No parameters, no return value
func PrintHello() {
fmt.Println("Hello")
}
// Called like this:
PrintHello()
// One parameter, one return value
func Hello(name string) string {
return "Hello " + name
}
// Called like this:
greeting := Hello("Dave")
// Multiple parameters, multiple return values
func SumAndMultiply(a, b int) (int, int) {
return a+b, a*b
}
// Called like this:
aplusb, atimesb := SumAndMultiply(a, b)
A paraméterekhez hasonlóan a visszatérési értékeket is el lehet nevezni.
Ha nevesített visszatérési értékeket használunk, akkor egy argumentum nélküli return utasítás ezeket az értékeket adja vissza.
Ezt nevezik „csupasz” visszatérésnek.
func SumAndMultiplyThenMinus(a, b, c int) (sum, mult int) {
sum, mult = a+b, a*b
sum -= c
mult -= c
return
}
Az is fontos, hogy tisztázzuk az érték szerinti és a referenciaszerinti átadás fogalmát.
Először tisztázzuk az érték szerinti átadást.
Az alábbi példában, amikor a val változót átadjuk a MultiplyByTwo függvénynek, a val egy másolatát adjuk át.
Emiatt a newVal a frissített 4 értéket kapja, az eredeti val változó viszont továbbra is 2.
A színfalak mögött a Go lényegében másolatot készít az eredeti értékről, így a függvény csak ezt a másolatot, azaz v-t módosítja.
val := 2
func MultiplyByTwo(v int) int {
v = v * 2
return v
}
newVal := MultiplyByTwo(val)
// newval is 4, val is still 2 because only a copy of its value was passed into the function
Szigorúan véve a Go-ban minden argumentum érték szerint adódik át, azaz másolat készül a függvénynek átadott értékről vagy adatról.
Ha viszont nem szeretnéd lemásolni a függvénynek átadott adatot, és a függvényen belül szeretnéd módosítani azt,
akkor argumentumként pointers-t kell használnod, ezt nevezik referenciaszerinti átadásnak.
A referenciaszerinti átadást egy pointer használatával érhetjük el.
Ha pointer argumentumokat adunk át egy függvénynek,
akkor a függvénynek átadott mögöttes adatot módosíthatjuk ahelyett, hogy csak az adat egy másolatán dolgoznánk.
Egyelőre elég annyit tudnod, hogy a mutatótípusokat a függvényszignatúrában a típus előtti * jelről ismerheted fel.
func HandlePointers(x, y *int) {
// Some logic to handle integer values referenced by pointers x and y
}
Ha zavarosnak tűnik a pointer fogalma, ne aggódj.
A tantervben később egy külön szakasz segít elsajátítani a mutatókat.
Vedd figyelembe, hogy a slices és a maps kivételt képez a fent említett szabály alól.
Amikor egy slice-ot vagy egy map-et argumentumként adunk át egy függvénynek, azokat a nyelv mutatótípusként kezeli, még akkor is, ha a típusban nincs kifejezett *.
Ez azt jelenti, hogy ha egy slice-ot vagy map-et adunk át egy függvénynek, és módosítjuk a mögöttes adatát,
a változások az eredeti slice-on vagy map-en is megjelennek.
Ebben a feladatban még egy kis kódot írunk, ami a kedvenc szakácskönyvedből származó ragyogó lasagnéd elkészítéséhez és megsütéséhez kapcsolódik.
Négy részfeladatod van. Az első magához a sütéshez kapcsolódik, a másik három a tökéletes előkészítésről szól.
Arra a következő lasagnéra, amit el fogsz készíteni, szeretnél elég időt félretenni, hogy élvezhesd a főzést. Már megtervezted, milyen rétegei lesznek a lasagnédnak. Most ezek alapján szeretnéd megbecsülni, mennyi ideig tart majd az előkészítés.
Készíts egy PreparationTime függvényt, amely egy rétegekből álló slice-ot []string típusként, valamint a rétegenkénti átlagos előkészítési időt percben int típusként fogad.
A függvény a rétegek száma alapján becsülje meg és adja vissza a teljes előkészítési időt int típusként.
A Go-ban a függvényeknek nincs alapértelmezett értékük.
Ha az átlagos előkészítési időt 0-ként adják át (ami az int alapértelmezett kezdőértéke), akkor a 2 alapértelmezett értéket kell használni.
layers := []string{"sauce", "noodles", "sauce", "meat", "mozzarella", "noodles"}
PreparationTime(layers, 3)
// => 18
PreparationTime(layers, 0)
// => 12
Amellett, hogy időt szánsz rá, szeretnéd azt is biztosítani, hogy legyen elég szósz és tészta az álmaid lasagnéjának elkészítéséhez. A lasagnéd minden tésztarétegéhez 50 gramm tésztára lesz szükséged. A lasagnéd minden szószrétegéhez 0,2 liter szószra lesz szükséged.
Definiáld a Quantities függvényt, amely paraméterként egy rétegekből álló slice-ot vesz át []string típusként.
A függvény ezután meghatározza, mennyi tésztára és szószra lesz szükség az ételed elkészítéséhez.
Az eredményt két értékként kell visszaadni: noodles int típusként és sauce float64 típusként.
Quantities([]string{"sauce", "noodles", "sauce", "meat", "mozzarella", "noodles"})
// => 100, 0.4
Nemrég meglátogattál egy barátodat, és lasagnét ettél nála. Fantasztikus volt, és volt benne valami különleges. A barátod elküldte az összetevők listáját, és elmondta, hogy a lista utolsó eleme a „titkos összetevő”, amitől az étel olyan különleges lett. Most ezt a titkos összetevőt a saját receptedhez is hozzá szeretnéd adni.
Írj egy AddSecretIngredient függvényt, amely paraméterként két []string típusú összetevőslice-ot fogad.
Az első paraméter a barátod által küldött lista, a második a saját recepted összetevőlistája.
Az összetevőlistád utolsó eleme mindig "?".
A függvény cserélje le ezt a barátod listájának utolsó elemére.
Megjegyzés: az AddSecretIngredient nem ad vissza semmit, közvetlenül a saját összetevőlistádat kell módosítanod.
A barátod összetevőit tartalmazó listát nem szabad módosítani.
Ráadásul, mivel a slice pointerként kerül át a függvénybe, az AddSecretIngredient függvénynek átadott két []string argumentum módosításai közvetlenül érvényesülnek.
friendsList := []string{"noodles", "sauce", "mozzarella", "kampot pepper"}
myList := []string{"noodles", "meat", "sauce", "mozzarella","?"}
AddSecretIngredient(friendsList, myList)
// myList => []string{"noodles", "meat", "sauce", "mozzarella", "kampot pepper"}
A szakácskönyvedben szereplő mennyiségek csak két adagra elegendő lasagnét adnak. Mivel legközelebb több embernek szeretnél főzni, ki szeretnéd számítani a mennyiségeket különböző adagszámokhoz.
Készíts egy ScaleRecipe függvényt, amely két paramétert fogad.
float64 típusú slice-ot a 2 adaghoz szükséges mennyiségekkel.A függvény egy float64 típusú slice-ot adjon vissza a kívánt adagszámhoz szükséges mennyiségekkel.
Az eredeti receptet viszont meg szeretnéd tartani.
Ez azt jelenti, hogy a quantities argumentumot nem szabad módosítani ebben a függvényben.
quantities := []float64{ 1.2, 3.6, 10.5 }
scaledQuantities := ScaleRecipe(quantities, 4)
// => []float64{ 2.4, 7.2, 21 }
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Go nyelvet 34 fogalom166 feladat segítségével, valódi emberi mentorálással, mindez ingyen.