Kurzusok
/
Go
Go
/
Feladatok
/
Kártyatrükkök
Kártyatrükkök

Kártyatrükkök

Tanulófeladat

Bevezetés

Szeletek

A Go szeletei más nyelvek listáihoz vagy tömbjeihez hasonlítanak. Egy adott típus (vagy interfész) több elemét tárolják.

A Go szeletei tömbökön alapulnak. A tömbök mérete fix. A szelet ezzel szemben egy tömb elemeinek dinamikus méretű, rugalmas nézete.

A szeletet []T formában írjuk le, ahol T a szelet elemeinek típusa:

var empty []int                 // an empty slice
withData := []int{0,1,2,3,4,5}  // a slice pre-filled with some data

Egy elemet egy adott nullaalapú indexen szögletes zárójeles jelöléssel kérhetsz le vagy állíthatsz be:

withData[1] = 5
x := withData[1] // x is now 5

Új szeletet hozhatsz létre egy meglévő szeletből úgy, hogy egy elemtartományt kérsz le. Megint szögletes zárójeles jelölést használunk, de megadjuk a kezdő (inkluzív) és a záró (exkluzív) indexet is. Ha nem adsz meg kezdő indexet, az alapértelmezés 0. Ha nem adsz meg záró indexet, az alapértelmezés a szelet hossza.

newSlice := withData[2:4]
// => []int{2,3}
newSlice := withData[:2]
// => []int{0,1}
newSlice := withData[2:]
// => []int{2,3,4,5}
newSlice := withData[:]
// => []int{0,1,2,3,4,5}

Elemeket az append függvénnyel adhatsz a szelethez. Az alábbi példában a 4-et és a 2-t fűzzük az a szelethez.

a := []int{1, 3}
a = append(a, 4, 2)
// => []int{1,3,4,2}

Az append mindig új szeletet ad vissza, és ha csak elemeket szeretnénk egy meglévő szelethez fűzni, gyakran ugyanahhoz a szeletváltozóhoz rendeljük vissza az eredményt, amelyet első argumentumként átadtunk, ahogy fent is tettük.

Az append két szelet összefűzésére is használható:

nextSlice := []int{100,101,102}
newSlice  := append(withData, nextSlice...)
// => []int{0,1,2,3,4,5,100,101,102}

Variádikus függvények

A Go-ban a függvények általában csak rögzített számú argumentumot fogadnak el. A Go-ban azonban variádikus függvényeket is írhatunk.

A variádikus függvény olyan függvény, amely változó számú argumentumot fogad el.

Ha egy függvénydefinícióban az utolsó paraméter típusa előtt három pont (...) áll, akkor a függvény ahhoz a paraméterhez tetszőleges számú argumentumot fogadhat el.

func find(a int, b ...int) {
    // ...
}

A fenti függvényben a b paraméter variádikus, és 0 vagy több argumentumot adhatunk át neki.

find(5, 6)
find(5, 6, 7)
find(5)
Caution

A variádikus paraméternek a függvény utolsó paraméterének kell lennie.

A variádikus függvények úgy működnek, hogy a változó számú argumentumot a variádikus paraméter típusának megfelelő szeletté alakítják.

Íme egy példa egy variádikus függvény megvalósítására.

func find(num int, nums ...int) {
    fmt.Printf("type of nums is %T\n", nums)

    for i, v := range nums {
        if v == num {
            fmt.Println(num, "found at index", i, "in", nums)
            return
        }
    }

    fmt.Println(num, "not found in ", nums)
}

func main() {
    find(89, 90, 91, 95)
    // =>
    // type of nums is []int
    // 89 not found in  [90 91 95]

    find(45, 56, 67, 45, 90, 109)
    // =>
    // type of nums is []int
    // 45 found at index 2 in [56 67 45 90 109]

    find(87)
    // =>
    // type of nums is []int
    // 87 not found in  []
}

A fenti program find(89, 90, 91, 95) sorában a find függvény változó számú argumentuma a 90, a 91 és a 95. A find függvény a num után egy variádikus int paramétert vár. Ezért ezt a három argumentumot a fordító int típusú szeletté alakítja ([]int{90, 91, 95}), majd nums néven átadja a find függvénynek.

Előfordul, hogy már van egy szeleted, és szeretnéd átadni egy variádikus függvénynek. Ezt úgy teheted meg, hogy a szelet után ...-ot adsz át. Ez jelzi a fordítónak, hogy a szeletet változatlanul használja a variádikus függvényben. A fent leírt, szeletet létrehozó lépés ebben az esetben egyszerűen elmarad.

list := []int{1, 2, 3}
find(1, list...) // "find" defined as shown above

Utasítások

Kezdő bűvészként Elyse-nek gyakorolnia kell néhány alapvető dolgot. Van egy pakli kártyája, amit szeretne ügyesen kezelni.

Hogy egy kicsit könnyebb legyen a dolga, csak az 1-től 10-ig terjedő kártyákat használja.

1. Készíts egy slice-ot bizonyos kártyákból

Amikor a kártyáival gyakorol, Elyse szeret a pakli három kedvenc kártyájával kezdeni: a 2-essel, a 6-ossal és a 9-essel. Írj egy FavoriteCards nevű függvényt, amely egy slice-ot ad vissza ezekkel a kártyákkal, ebben a sorrendben.

cards := FavoriteCards()
fmt.Println(cards)
// Output: [2 6 9]

2. Kérj le egy kártyát a pakliból

Add vissza a megadott pakliból az index pozícióban lévő kártyát.

card := GetItem([]int{1, 2, 4, 1}, 2) // card == 4

Ha az index a pakli határain kívül esik (azaz negatív, vagy a pakli vége után van), akkor -1-et adunk vissza:

card := GetItem([]int{1, 2, 4, 1}, 10) // card == -1
Note

A Go-ban megszokás, hogy hibaértéket adunk vissza a „tartományon kívüli” érték helyett. Itt a „tartományon kívüli” érték a -1, amikor pozitív egész számot várunk. Hiba visszaadásakor idiomatikusnak számít a hiba mellett a zero value értéket is visszaadni. Hogy hogyan adjunk vissza hibát a megfelelő visszatérési értékkel, arról egy későbbi feladatban lesz szó.

3. Cserélj ki egy kártyát a pakliban

Cseréld ki a pakliban az index pozícióban lévő kártyát a megadott új kártyára, és add vissza a módosított paklit. Figyelj rá, hogy ez módosítani fogja a bemeneti slice-ot, ami az elvárt viselkedés.

index := 2
newCard := 6
cards := SetItem([]int{1, 2, 4, 1}, index, newCard)
fmt.Println(cards)
// Output: [1 2 6 1]

Ha az index a pakli határain kívül esik (azaz negatív, vagy a pakli vége után van), akkor az új kártyát a pakli végéhez fűzzük:

index := -1
newCard := 6
cards := SetItem([]int{1, 2, 4, 1}, index, newCard)
fmt.Println(cards)
// Output: [1 2 4 1 6]

4. Adj kártyákat a pakli tetejére

Add hozzá a value paraméterben megadott kártyát vagy kártyákat a pakli tetejéhez.

slice := []int{3, 2, 6, 4, 8}
cards := PrependItems(slice, 5, 1)
fmt.Println(cards)
// Output: [5 1 3 2 6 4 8]

Ha a value paraméterhez nem adunk meg argumentumot, akkor az eredmény megegyezik az eredeti slice-szal.

slice := []int{3, 2, 6, 4, 8}
cards := PrependItems(slice)
fmt.Println(cards)
// Output: [3 2 6 4 8]

5. Vegyél ki egy kártyát a pakliból

Távolítsd el a pakliból az index pozícióban lévő kártyát, és add vissza a paklit. Figyelj rá, hogy ez módosíthatja a bemeneti slice-ot, és ez így rendben van.

cards := RemoveItem([]int{3, 2, 6, 4, 8}, 2)
fmt.Println(cards)
// Output: [3 2 4 8]

Ha az index a pakli határain kívül esik (azaz negatív, vagy a pakli vége után van), akkor a paklit változatlanul hagyjuk:

cards := RemoveItem([]int{3, 2, 6, 4, 8}, 11)
fmt.Println(cards)
// Output: [3 2 6 4 8]
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Go Exercism

Készen állsz elkezdeni a(z) Kártyatrükkök feladatot?

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.