Kurzusok
/
Go
Go
/
Feladatok
/
Lasagne-mester
Lasagne-mester

Lasagne-mester

Tanulófeladat

Bevezetés

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.

Függvényparaméterek

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)
}

Paraméterek és argumentumok

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")

Visszatérési értékek

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
}

Függvények meghívása

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)

Nevesített visszatérési értékek és csupasz visszatérés

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
}

Érték szerinti és referenciaszerinti átadás

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.

Mutatók

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.

Kivételek

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.

Utasítások

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.

1. Becsüld meg az előkészítési időt

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

2. Számítsd ki a szükséges tészta és szósz mennyiségét

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

3. Add hozzá a titkos összetevőt

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"}

4. Méretezd át a receptet

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.

  • Egy float64 típusú slice-ot a 2 adaghoz szükséges mennyiségekkel.
  • Az elkészíteni kívánt adagok számát.

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 }
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Go Exercism

Készen állsz elkezdeni a(z) Lasagne-mester feladatot?

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.