diff options
Diffstat (limited to 'hu-hu/go.html.markdown')
-rw-r--r-- | hu-hu/go.html.markdown | 444 |
1 files changed, 237 insertions, 207 deletions
diff --git a/hu-hu/go.html.markdown b/hu-hu/go.html.markdown index b3e8c1ca..460e23ec 100644 --- a/hu-hu/go.html.markdown +++ b/hu-hu/go.html.markdown @@ -1,8 +1,7 @@ --- -name: Go -category: language language: Go -filename: learngo.go +lang: hu-hu +filename: learngo-hu.go contributors: - ["Sonia Keys", "https://github.com/soniakeys"] translators: @@ -20,276 +19,307 @@ a mai számítógépek több magos processzorait, ez nagy rendszerek építésé A Go alap könyvtára mindenre területre kiterjed, ennek köszönhetően a nyelvnek egyre növekvő tábora van. -```Go +```go // Egy soros komment /* Több soros komment */ -// Minden forrás fájl egy csomag-definícióval kezdődik, ez hasonlít a Python csomagkezelésére -// A main egy különleges csomagnév, ennek a fordítása futtatható állományt hoz létre egy könyvtár helyett. +// Minden forrás fájl egy csomag-definícióval kezdődik, ez hasonlít a Python +// csomagkezelésére +// A main egy különleges csomagnév, ennek a fordítása futtatható állományt hoz +// létre egy könyvtár helyett. package main -// Az import rész meghatározza melyik csomagokat kívánjuk használni ebben a forrásfájlban +// Az import rész meghatározza melyik csomagokat kívánjuk használni ebben a +// forrásfájlban import ( - "fmt" // A Go alap könyvtárának része - "net/http" // Beépített webszerver! - "strconv" // Stringek átalakítására szolgáló csomag + "fmt" // A Go alap könyvtárának része + "net/http" // Beépített webszerver! + "strconv" // Stringek átalakítására szolgáló csomag ) // Funkció deklarás, a main nevű funkció a program kezdőpontja. func main() { - // Println kiírja a beadott paramétereket a standard kimenetre. - // Ha más csomagot funkcióját akarjuk használni, akkor azt jelezni kell a csomag nevével - fmt.Println("Hello world!") + // Println kiírja a beadott paramétereket a standard kimenetre. + // Ha más csomagot funkcióját akarjuk használni, akkor azt jelezni kell a + // csomag nevével + fmt.Println("Hello world!") - // Meghívunk egy másik funkciót ebből a csomagból - beyondHello() + // Meghívunk egy másik funkciót ebből a csomagból + beyondHello() } // A függvények paraméterei zárójelek között vannak. // Ha nincsenek paraméterek, akkor is kötelező a zárójel-pár. func beyondHello() { - var x int // Változó deklaráció, használat előtt muszáj ezt megtenni. - x = 3 // Változó értékadás - // "Rövid" deklaráció is létezik, ez az érték alapján deklarálja, definiálja és értéket is ad a változónak - y := 4 - sum, prod := learnMultiple(x, y) // a függvényeknek több visszatérési értéke is lehet - fmt.Println("sum:", sum, "prod:", prod) // egyszerű kiíratás - learnTypes() + var x int // Változó deklaráció, használat előtt muszáj ezt megtenni. + x = 3 // Változó értékadás + // "Rövid" deklaráció is létezik, ez az érték alapján deklarálja, + // definiálja és értéket is ad a változónak + y := 4 + sum, prod := learnMultiple(x, y) // a függvényeknek több + // visszatérési értéke is lehet + fmt.Println("sum:", sum, "prod:", prod) // egyszerű kiíratás + learnTypes() } // A funkcióknak elnevezett visszatérési értékük is lehet func learnMultiple(x, y int) (sum, prod int) { - return x + y, x * y // visszatérünk két értékkel - /* - sum = x + y - prod = x * y - return - Ez ugyanezzel az eredménnyel járt volna, mint a fenti sor. - Üres return esetén, az elnevezett visszatérési változók - aktuális értékeikkel térnek vissza. */ + return x + y, x * y // visszatérünk két értékkel + /* + sum = x + y + prod = x * y + return + Ez ugyanezzel az eredménnyel járt volna, mint a fenti sor. + Üres return esetén, az elnevezett visszatérési változók + aktuális értékeikkel térnek vissza. */ } // Beépített típusok func learnTypes() { - // Rövid deklarás az esetek többségében elég lesz a változókhoz - s := "Tanulj Go-t!" // string típus - - s2 := `A "nyers" stringekben lehetnek - újsorok is!` // de ettől még ez is ugyanolyan string mint az s, nincs külön típusa - - // nem ASCII karakterek. Minden Go forrás UTF-8 és a stringek is azok. - g := 'Σ' // rúna(rune) típus, megegyezik az uint32-vel, egy UTF-8 karaktert tárol - - f := 3.14195 // float64, az IEEE-754 szabványnak megfelelő 64-bites lebegőpontos szám - c := 3 + 4i // complex128, belsőleg két float64-el tárolva - - // Var szintaxis változó típus definiálással - var u uint = 7 // unsigned, az implementáció dönti el mekkora, akárcsak az int-nél - var pi float32 = 22. / 7 - - // Rövid deklarásnál átalakítás is lehetséges - n := byte('\n') // byte típus, ami megegyezik az uint8-al - - // A tömböknek fordítás-időben fixált méretük van - var a4 [4]int // egy tömb 4 int-tel, mind 0-ra inicializálva - a3 := [...]int{3, 1, 5} // egy tömb 3 int-tel, láthatóan inicalizálva egyedi értékekre - - // Szeleteknek dinamikus a méretük. A szeleteknek és a tömböknek is meg vannak az előnyeik - // de a szeleteket sokkal gyakrabban használjuk. - s3 := []int{4, 5, 9} // vesd össze a3-al, nincsenek pontok. - s4 := make([]int, 4) // allokál 4 int-et, mind 0-ra inicializálva - var d2 [][]float64 // ez csak deklaráció, semmi sincs még allokálva - bs := []byte("a slice") // típus konverzió szintaxisa - - p, q := learnMemory() // deklarál két mutatót (p,q), két int-re - fmt.Println(*p, *q) // * követi a mutatót. Ez a sor kiírja a két int értékét. - - // A map a dinamikusan növelhető asszociatív tömb része a nyelvnek, hasonlít - // a hash és dictionary típusokra más nyelvekben. - m := map[string]int{"three": 3, "four": 4} - m["one"] = 1 - - // A felhasználatlan változók fordítás-idejű hibát okoznak a Go-ban. - // Az aláhúzással "használod" a változókat, de eldobod az értéküket. - _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs - // Kiíratás is természetesen használatnak minősül - fmt.Println(s, c, a4, s3, d2, m) - - learnFlowControl() + // Rövid deklarás az esetek többségében elég lesz a változókhoz + s := "Tanulj Go-t!" // string típus + + s2 := `A "nyers" stringekben lehetnek + újsorok is!` // de ettől még ez is ugyanolyan string mint az s, nincs külön + // típusa + + // nem ASCII karakterek. Minden Go forrás UTF-8 és a stringek is azok. + g := 'Σ' // rúna(rune) típus, megegyezik az uint32-vel, egy UTF-8 karaktert + // tárol + + f := 3.14195 // float64, az IEEE-754 szabványnak megfelelő 64-bites + // lebegőpontos szám + c := 3 + 4i // complex128, belsőleg két float64-el tárolva + + // Var szintaxis változó típus definiálással + var u uint = 7 // unsigned, az implementáció dönti el mekkora, akárcsak az + // int-nél + var pi float32 = 22. / 7 + + // Rövid deklarásnál átalakítás is lehetséges + n := byte('\n') // byte típus, ami megegyezik az uint8-al + + // A tömböknek fordítás-időben fixált méretük van + var a4 [4]int // egy tömb 4 int-tel, mind 0-ra inicializálva + a3 := [...]int{3, 1, 5} // egy tömb 3 int-tel, láthatóan inicalizálva egyedi + // értékekre + + // Szeleteknek dinamikus a méretük. A szeleteknek és a tömböknek is meg + // vannak az előnyeik de a szeleteket sokkal gyakrabban használjuk. + s3 := []int{4, 5, 9} // vesd össze a3-al, nincsenek pontok. + s4 := make([]int, 4) // allokál 4 int-et, mind 0-ra inicializálva + var d2 [][]float64 // ez csak deklaráció, semmi sincs még allokálva + bs := []byte("a slice") // típus konverzió szintaxisa + + p, q := learnMemory() // deklarál két mutatót (p,q), két int-re + fmt.Println(*p, *q) // * követi a mutatót. Ez a sor kiírja a két int értékét. + + // A map a dinamikusan növelhető asszociatív tömb része a nyelvnek, hasonlít + // a hash és dictionary típusokra más nyelvekben. + m := map[string]int{"three": 3, "four": 4} + m["one"] = 1 + + // A felhasználatlan változók fordítás-idejű hibát okoznak a Go-ban. + // Az aláhúzással "használod" a változókat, de eldobod az értéküket. + _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs + // Kiíratás is természetesen használatnak minősül + fmt.Println(s, c, a4, s3, d2, m) + + learnFlowControl() } -// A Go nyelv teljesen szemétgyűjtött (garbage-collected). Megtalálhatók benne mutatók, de nincs mutató aritmetika. -// Ez azt jelenti, hogy üres mutatóval még mindig hibázhatsz, de hozzáadni/műveleteket végezni már nem lehet. +// A Go nyelv teljesen szemétgyűjtött (garbage-collected). Megtalálhatók benne +// mutatók, de nincs mutató aritmetika. Ez azt jelenti, hogy üres mutatóval még +// mindig hibázhatsz, de hozzáadni/műveleteket végezni már nem lehet. func learnMemory() (p, q *int) { - // Elnevezett visszatérési változóknak int-re mutató a típusa - p = new(int) // a beépített "new" funkció, egy típusnak elegendő memóriát allokál, és visszaad rá egy mutatót. - // Az allokált int nullázva van, p többé nem üres mutató. - s := make([]int, 20) // allokáljunk 20 int változót egy memóriaterületen. - s[3] = 7 // adjunk értéket az egyiknek - r := -2 // hozzánk létre egy lokális változót - return &s[3], &r // A & megadja a memóriacímét a változónak + // Elnevezett visszatérési változóknak int-re mutató a típusa + p = new(int) // a beépített "new" funkció, egy típusnak elegendő memóriát + // allokál, és visszaad rá egy mutatót. + // Az allokált int nullázva van, p többé nem üres mutató. + s := make([]int, 20) // allokáljunk 20 int változót egy memóriaterületen. + s[3] = 7 // adjunk értéket az egyiknek + r := -2 // hozzánk létre egy lokális változót + return &s[3], &r // A & megadja a memóriacímét a változónak } func expensiveComputation() int { - return 1e6 + return 1e6 } func learnFlowControl() { - // Az elágazásoknak kötelező a kapcsos zárójel, a zárójel nem szükséges. - if true { - fmt.Println("megmondtam") - } - // A kód formátumát a nyelvvel járó "go" parancssori program "go fmt" parancsa szabványosítja - if false { - // így lehet - } else { - // if/else-t csinálni - } - // Használjunk switchet a hosszabb elágazások alkalmazása helyett. - x := 1 - switch x { - case 0: - case 1: - // Az "esetek" nem "esnek át", tehát - case 2: - // ez nem fog lefutni, nincs szükség break-ekre. - } - // A for ciklus sem használ zárójeleket - for x := 0; x < 3; x++ { - fmt.Println("iteráció", x) - } - // itt az x == 1. - - // A for az egyetlen ciklus fajta a Go-ban, de több formája van. - for { // végtelen ciklus - break // csak vicceltem - continue // soha nem fut le - } - // Akárcsak a for-nál, az if-ben is lehet rövid deklarással egy lokális változót létrehozni - // ami az blokk összes if/else-n keresztül érvényes marad. - if y := expensiveComputation(); y > x { - x = y - } - // Függvényeket használhatjuk closure-ként is. - xBig := func() bool { - return x > 100 // a switch felett deklarált x-et használjuk itt - } - fmt.Println("xBig:", xBig()) // igaz (utoljára 1e6 lett az értéke az x-nek) - x /= 1e5 // így most már x == 10 - fmt.Println("xBig:", xBig()) // 10 pedig kisebb mint 100, tehát hamis - - // Ha nagyon-nagyon szükséges, akkor használhatjuk a jó öreg goto-t. - goto love + // Az elágazásoknak kötelező a kapcsos zárójel, a zárójel nem szükséges. + if true { + fmt.Println("megmondtam") + } + // A kód formátumát a nyelvvel járó "go" parancssori program "go fmt" + // parancsa szabványosítja + if false { + // így lehet + } else { + // if/else-t csinálni + } + // Használjunk switchet a hosszabb elágazások alkalmazása helyett. + x := 1 + switch x { + case 0: + case 1: + // Az "esetek" nem "esnek át", tehát + case 2: + // ez nem fog lefutni, nincs szükség break-ekre. + } + // A for ciklus sem használ zárójeleket + for x := 0; x < 3; x++ { + fmt.Println("iteráció", x) + } + // itt az x == 1. + + // A for az egyetlen ciklus fajta a Go-ban, de több formája van. + for { // végtelen ciklus + break // csak vicceltem + continue // soha nem fut le + } + // Akárcsak a for-nál, az if-ben is lehet rövid deklarással egy lokális + // változót létrehozni ami az blokk összes if/else-n keresztül érvényes + // marad. + if y := expensiveComputation(); y > x { + x = y + } + // Függvényeket használhatjuk closure-ként is. + xBig := func() bool { + return x > 100 // a switch felett deklarált x-et használjuk itt + } + fmt.Println("xBig:", xBig()) // igaz (utoljára 1e6 lett az értéke az x-nek) + x /= 1e5 // így most már x == 10 + fmt.Println("xBig:", xBig()) // 10 pedig kisebb mint 100, tehát hamis + + // Ha nagyon-nagyon szükséges, akkor használhatjuk a jó öreg goto-t. + goto love love: - learnInterfaces() // Itt kezdődnek az érdekes dolgok! + learnInterfaces() // Itt kezdődnek az érdekes dolgok! } -// Definiáljuk a Stringert egy olyan interfésznek, amelynek egy metódusa van, a String, ami visszatér egy stringgel. +// Definiáljuk a Stringert egy olyan interfésznek, amelynek egy metódusa van, a +// String, ami visszatér egy stringgel. type Stringer interface { - String() string + String() string } -// Definiáljuk a pair-t egy olyan struktúrának amelynek két int változója van, x és y. +// Definiáljuk a pair-t egy olyan struktúrának amelynek két int változója van, +// x és y. type pair struct { - x, y int + x, y int } -// Definiáljunk egy metódust a pair struktúrának, ezzel teljesítve a Stringer interf +// Definiáljunk egy metódust a pair struktúrának, ezzel teljesítve a Stringer +// interf func (p pair) String() string { // p lesz a "vevő" - // Sprintf az fmt csomag egy publikus függvénye, műkődése megegyezik a C-s megfelelőjével. - // A pontokkal érjük el a mindenkori p struktúra elemeit - return fmt.Sprintf("(%d, %d)", p.x, p.y) + // Sprintf az fmt csomag egy publikus függvénye, műkődése megegyezik a C-s + // megfelelőjével. A pontokkal érjük el a mindenkori p struktúra elemeit + return fmt.Sprintf("(%d, %d)", p.x, p.y) } func learnInterfaces() { - // A kapcsos zárójellel jelezzük, hogy egyből inicializálni - // szeretnénk a struktúra változóit a sorrendnek megfelelően. - p := pair{3, 4} - fmt.Println(p.String()) // meghívjuk a p String metódusát. - var i Stringer // deklaráljuk i-t Stringer típusú interfésznek - i = p // lehetséges, mert a pair struktúra eleget tesz a Stringer interfésznek - // Meghívjuk i String metódusát, az eredmény ugyanaz, mint az előbb. - fmt.Println(i.String()) - - // Az fmt csomag funckciói automatikusan meghívják a String funkciót - // hogy megtudják egy objektum szöveges reprezentációját. - fmt.Println(p) // ugyan az az eredmény mint az előbb, a Println meghívja a String metódust. - fmt.Println(i) // dettó - - learnErrorHandling() + // A kapcsos zárójellel jelezzük, hogy egyből inicializálni + // szeretnénk a struktúra változóit a sorrendnek megfelelően. + p := pair{3, 4} + fmt.Println(p.String()) // meghívjuk a p String metódusát. + var i Stringer // deklaráljuk i-t Stringer típusú interfésznek + i = p // lehetséges, mert a pair struktúra eleget tesz a + // Stringer interfésznek + // Meghívjuk i String metódusát, az eredmény ugyanaz, mint az előbb. + fmt.Println(i.String()) + + // Az fmt csomag funckciói automatikusan meghívják a String funkciót + // hogy megtudják egy objektum szöveges reprezentációját. + fmt.Println(p) // ugyan az az eredmény mint az előbb, a Println meghívja + // a String metódust. + fmt.Println(i) // dettó + + learnErrorHandling() } func learnErrorHandling() { - // ", ok" szokásos megoldás arra, hogy jól működött-e a függvény. - m := map[int]string{3: "three", 4: "four"} - if x, ok := m[1]; !ok { // ok hamis lesz, mert az 1 nincs benne a map-ban. - fmt.Println("nincs meg") - } else { - fmt.Print(x) // x lenne az érték, ha benne lenne a map-ban. - } - // A hiba érték többet is elmond a függvény kimeneteléről, mint hogy minden "ok" volt-e - if _, err := strconv.Atoi("non-int"); err != nil { // _ eldobja az értéket, úgy se lesz jó jelen esetben - // kiírja, hogy "strconv.ParseInt: parsing "non-int": invalid syntax" - fmt.Println(err) - } - // Az interfészekre még visszatérünk, addig is jöjjön a konkurens programozás! - learnConcurrency() + // ", ok" szokásos megoldás arra, hogy jól működött-e a függvény. + m := map[int]string{3: "three", 4: "four"} + if x, ok := m[1]; !ok { // ok hamis lesz, mert az 1 nincs benne a map-ban. + fmt.Println("nincs meg") + } else { + fmt.Print(x) // x lenne az érték, ha benne lenne a map-ban. + } + // A hiba érték többet is elmond a függvény kimeneteléről, mint hogy minden + // "ok" volt-e + if _, err := strconv.Atoi("non-int"); err != nil { // _ eldobja az értéket, + // úgy se lesz jó jelen + // esetben + // kiírja, hogy "strconv.ParseInt: parsing "non-int": invalid syntax" + fmt.Println(err) + } + // Az interfészekre még visszatérünk, addig is jöjjön a konkurens programozás! + learnConcurrency() } // c egy csatorna, egy konkurens-biztos kommunikációs objektum. func inc(i int, c chan int) { - c <- i + 1 // <- a "küldés" operátor, ha a bal oldalán csatorna van, így i+1-et küld be a csatornába + c <- i + 1 // <- a "küldés" operátor, ha a bal oldalán csatorna van, így + // i+1-et küld be a csatornába } // Az inc-et fogjuk arra használni, hogy konkurensen megnöveljünk számokat func learnConcurrency() { - // Ugyan az a make funkció amivel korábban szeleteket hoztunk létre. - // Make allokál mapokat, szeleteket és csatornákat. - c := make(chan int) - // Indítsunk három konkurens goroutine-t. A számok konkurensen lesznek - // megnövelve, ha a számítógép képes rá és jól be van állítva, akkor pedig paralellizálva/egymás mellett. - // Mind a 3 ugyanabba a csatornába küldi az eredményeket. - go inc(0, c) // A go utasítás indít el goroutine-okat. - go inc(10, c) - go inc(-805, c) - // Beolvassuk 3x a csatornából az eredményeket és kiírjuk őket a kimenetre. - // Nem lehet tudni milyen sorrendben fognak érkezni az eredmények! - fmt.Println(<-c, <-c, <-c) // hogyha a jobb oldalon csatorna van, akkor a "<-" a beolvasó/kapó operátor - - cs := make(chan string) // még egy csatorna, ez stringekkel kommunikál - cc := make(chan chan string) // egy csatorna csatornával - go func() { c <- 84 }() // indítsunk egy új goroutine-t, csak azért hogy küldjünk egy számot - go func() { cs <- "wordy" }() // ugyanez, csak a cs csatornába stringet küldünk - // A select olyan mint a switch, csak feltételek helyett csatorna műveletek vannak. - // Véletlenszerűen kiválasztja az első olyan esetet, ahol létrejöhet kommunikáció. - select { - case i := <-c: // a megkapott értéket el lehet tárolni egy változóban - fmt.Println("ez egy", i) - case <-cs: // vagy el lehet dobni az értékét - fmt.Println("ez egy string volt") - case <-cc: // üres csatorna, soha nem fog rajta semmi se érkezni - fmt.Println("sose futok le :'( ") - } - // Ezen a ponton vagy c vagy a cs goroutineja lefutott. - // Amelyik hamarabb végzett, annak a megfelelő case-e lefutott, a másik blokkolva vár. - - learnWebProgramming() // Go képes rá. Te is képes akarsz rá lenni. + // Ugyan az a make funkció amivel korábban szeleteket hoztunk létre. + // Make allokál mapokat, szeleteket és csatornákat. + c := make(chan int) + // Indítsunk három konkurens goroutine-t. A számok konkurensen lesznek + // megnövelve, ha a számítógép képes rá és jól be van állítva, akkor pedig + // paralellizálva/egymás mellett. Mind a 3 ugyanabba a csatornába küldi az + // eredményeket. + go inc(0, c) // A go utasítás indít el goroutine-okat. + go inc(10, c) + go inc(-805, c) + // Beolvassuk 3x a csatornából az eredményeket és kiírjuk őket a kimenetre. + // Nem lehet tudni milyen sorrendben fognak érkezni az eredmények! + fmt.Println(<-c, <-c, <-c) // hogyha a jobb oldalon csatorna van, akkor a + // "<-" a beolvasó/kapó operátor + + cs := make(chan string) // még egy csatorna, ez stringekkel kommunikál + cc := make(chan chan string) // egy csatorna csatornával + go func() { c <- 84 }() // indítsunk egy új goroutine-t, csak azért + // hogy küldjünk egy számot + go func() { cs <- "wordy" }() // ugyanez, csak a cs csatornába stringet + // küldünk + // A select olyan mint a switch, csak feltételek helyett csatorna műveletek + // vannak. Véletlenszerűen kiválasztja az első olyan esetet, ahol létrejöhet + // kommunikáció. + select { + case i := <-c: // a megkapott értéket el lehet tárolni egy változóban + fmt.Println("ez egy", i) + case <-cs: // vagy el lehet dobni az értékét + fmt.Println("ez egy string volt") + case <-cc: // üres csatorna, soha nem fog rajta semmi se érkezni + fmt.Println("sose futok le :'( ") + } + // Ezen a ponton vagy c vagy a cs goroutineja lefutott. + // Amelyik hamarabb végzett, annak a megfelelő case-e lefutott, a másik + // blokkolva vár. + + learnWebProgramming() // Go képes rá. Te is képes akarsz rá lenni. } // Egy funkció a http csomagból elindít egy webszervert. func learnWebProgramming() { - // A ListenAndServe első paramétre egy TCP port, amin kiszolgálunk majd. - // Második paramétere egy interfész, pontosabban a http.Handler interfész. - err := http.ListenAndServe(":8080", pair{}) - fmt.Println(err) // nem felejtük el kiírni az esetleges hibákat! + // A ListenAndServe első paramétre egy TCP port, amin kiszolgálunk majd. + // Második paramétere egy interfész, pontosabban a http.Handler interfész. + err := http.ListenAndServe(":8080", pair{}) + fmt.Println(err) // nem felejtük el kiírni az esetleges hibákat! } -// Csináljunk a pair-ból egy http.Handler-t úgy, hogy implementáljuk az egyetlen metódusát a ServeHTTP-t. +// Csináljunk a pair-ból egy http.Handler-t úgy, hogy implementáljuk az +// egyetlen metódusát a ServeHTTP-t. func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Minden kapcsolatra elküldjük ezt a http.ResponseWriter-el - w.Write([]byte("Megtanultad a Go-t Y perc alatt!")) + // Minden kapcsolatra elküldjük ezt a http.ResponseWriter-el + w.Write([]byte("Megtanultad a Go-t Y perc alatt!")) } ``` |