From f33dea8b83bf64ecde36337a5e02cae77f5210de Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 19 Aug 2013 09:14:02 -0700 Subject: Updates --- README.markdown | 41 ++++- bash.html.markdown | 43 +++-- groovy.html.markdown | 60 ++++--- hu-hu/go.html.markdown | 444 ++++++++++++++++++++++++++----------------------- 4 files changed, 338 insertions(+), 250 deletions(-) diff --git a/README.markdown b/README.markdown index efc2fa07..701b12d7 100644 --- a/README.markdown +++ b/README.markdown @@ -9,18 +9,47 @@ commented code and explained as they go. ... to write more inline code tutorials. Just grab an existing file from this repo and copy the formatting (don't worry, it's all very simple). Make a new file, send a pull request, and if it passes muster I'll get it up pronto. -Remember to fill in the author and author\_url fields so you get credited +Remember to fill in the "contributors" fields so you get credited properly! ### Requests -The most requested languages are: +We've had a ton of interest, b -* Go -* ~~Scala~~ -* ~~Javascript~~ +### Contributing -... but there are many more requests to do "every language", so don't let that stop you. +All contributions welcome, from the tiniest typo to a brand new article. Translations +in all languages are welcome (or, for that matter, original articles in any language). + +#### Style Guidelines + +* Try to keep **line length in code blocks to 80 characters or fewer**, or they'll overflow + and look odd. + +* Try to use as few words as possible. Code examples are preferred over exposition in all cases. + +* We welcome newcomers, but the target audience for this site is programmers with some experience. + So, try to avoid explaining basic concepts except for those specific to the language in question, + to keep articles succinct and scannable. We all know how to use google here. + +* For translations (or english articles with non-ASCII characters), please make sure your file is + utf-8 encoded. + +#### Header configuration + +The actual site uses Middleman to generate HTML files from these markdown ones. Middleman, or at least +the custom scripts underpinning the site, required that some key information be defined in the header. + +The following fields are necessary for english articles about programming languages: + +* **language** The *programming language* in question +* **contributors** A list of [author, url] lists to credit + +Other fields: + +* **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable. + For non-english articles, *filename* should have a language-specific suffix. +* **lang**: For translations, the human language this article is in. For categorization, mostly. ## License diff --git a/bash.html.markdown b/bash.html.markdown index 8cf7be18..7421f880 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -1,8 +1,10 @@ --- -language: bash +category: tool +tool: bash contributors: - - ["Max Yankov", "https://github.com/golergka" - "Darren Lin", "https://github.com/CogBear"] + - ["Max Yankov", "https://github.com/golergka"] + - ["Darren Lin", "https://github.com/CogBear"] filename: LearnBash.sh --- @@ -14,7 +16,8 @@ Nearly all examples below can be a part of a shell script or executed directly i ```bash #!/bin/sh -# First line of the script is shebang which tells the system how to execute the script: http://en.wikipedia.org/wiki/Shebang_(Unix) +# First line of the script is shebang which tells the system how to execute +# the script: http://en.wikipedia.org/wiki/Shebang_(Unix) # As you already figured, comments start with #. Shebang is also a comment. # Simple hello world example: @@ -27,12 +30,15 @@ echo 'This is the first line'; echo 'This is the second line' VARIABLE="Some string" # But not like this: -VARIABLE = "Some string" # Bash will decide that VARIABLE is a command he must execute and give an error because it couldn't be found. +VARIABLE = "Some string" +# Bash will decide that VARIABLE is a command it must execute and give an error +# because it couldn't be found. # Using the variable: echo $VARIABLE echo "$VARIABLE" -# When you use the variable itself — assign it, export it, or else — you write it's name without $. If you want to use variable's value, you should use $. +# When you use the variable itself — assign it, export it, or else — you write +# its name without $. If you want to use variable's value, you should use $. # Reading a value from input: echo "What's your name?" @@ -42,43 +48,46 @@ echo Hello, $NAME! # We have the usual if structure: if true then - echo "This is expected" + echo "This is expected" else - echo "And this is not" + echo "And this is not" fi # Expressions are denoted with the following format: echo $(( 10 + 5 )) -# Unlike other programming languages, bash is a shell — so it works in a context of current directory. -# You can list files and directories in the current directories with ls command: +# Unlike other programming languages, bash is a shell — so it works in a context +# of current directory. You can list files and directories in the current +# directories with ls command: ls # These commands have options that control their execution: ls -l # Lists every file and directory on a separate line # Results of the previous command can be passed to the next command as input. -# grep command filters the input with provided patterns. That's how we can list txt files in the current directory: +# grep command filters the input with provided patterns. That's how we can list +# txt files in the current directory: ls -l | grep "\.txt" # Commands can be substitued within other commands using $( ): -# The following command displays the number of files and directories in the current directory. +# The following command displays the number of files and directories in the +# current directory. echo "There are $(ls | wc -l) items here." -#Bash uses a case statement that works similarily to switch in Java and C++: +# Bash uses a case statement that works similarily to switch in Java and C++: case "$VARIABLE" in - #List patterns for the conditions you want to meet - 0) echo "There is a zero." - 1) echo "There is a one." - *) echo "It is not null." + #List patterns for the conditions you want to meet + 0) echo "There is a zero." + 1) echo "There is a one." + *) echo "It is not null." esac #For loops iterate for as many arguments given: #The contents of var $VARIABLE is printed three times. for $VARIABLE in x y z do - echo "$VARIABLE" + echo "$VARIABLE" done ``` diff --git a/groovy.html.markdown b/groovy.html.markdown index e4c2180b..1a635e59 100644 --- a/groovy.html.markdown +++ b/groovy.html.markdown @@ -112,14 +112,31 @@ println devMap.values() When Groovy is compiled to bytecode, the following rules are used. - * If the name is declared with an access modifier (public, private or protected) then a field is generated. - * A name declared with no access modifier generates a private field with public getter and setter (i.e. a property). - * If a property is declared final the private field is created final and no setter is generated. + * If the name is declared with an access modifier (public, private or + protected) then a field is generated. + + * A name declared with no access modifier generates a private field with + public getter and setter (i.e. a property). + + * If a property is declared final the private field is created final and no + setter is generated. + * You can declare a property and also declare your own getter or setter. - * You can declare a property and a field of the same name, the property will use that field then. - * If you want a private or protected property you have to provide your own getter and setter which must be declared private or protected. - * If you access a property from within the class the property is defined in at compile time with implicit or explicit this (for example this.foo, or simply foo), Groovy will access the field directly instead of going though the getter and setter. - * If you access a property that does not exist using the explicit or implicit foo, then Groovy will access the property through the meta class, which may fail at runtime. + + * You can declare a property and a field of the same name, the property will + use that field then. + + * If you want a private or protected property you have to provide your own + getter and setter which must be declared private or protected. + + * If you access a property from within the class the property is defined in + at compile time with implicit or explicit this (for example this.foo, or + simply foo), Groovy will access the field directly instead of going though + the getter and setter. + + * If you access a property that does not exist using the explicit or + implicit foo, then Groovy will access the property through the meta class, + which may fail at runtime. */ @@ -185,13 +202,14 @@ for ( e in map ) { /* Operators - Operator Overloading for a list of the common operators that Groovy supports: http://groovy.codehaus.org/Operator+Overloading + Operator Overloading for a list of the common operators that Groovy supports: + http://groovy.codehaus.org/Operator+Overloading Helpful groovy operators */ //Spread operator: invoke an action on all items of an aggregate object. def technologies = ['Groovy','Grails','Gradle'] -technologies*.toUpperCase() //equivalent to: technologies.collect { it?.toUpperCase() } +technologies*.toUpperCase() // = to technologies.collect { it?.toUpperCase() } //Safe navigation operator: used to avoid a NullPointerException. def user = User.get(1) @@ -200,7 +218,8 @@ def username = user?.username /* Closures - A Groovy Closure is like a "code block" or a method pointer. It is a piece of code that is defined and then executed at a later point. + A Groovy Closure is like a "code block" or a method pointer. It is a piece of + code that is defined and then executed at a later point. More info at: http://groovy.codehaus.org/Closures+-+Formal+Definition */ @@ -219,16 +238,13 @@ def x = 5 def multiplyBy = { num -> num * x } println multiplyBy(10) -//If you have a Closure that takes a single argument, you may omit the parameter definition of the Closure +// If you have a Closure that takes a single argument, you may omit the +// parameter definition of the Closure def clos = { print it } clos( "hi" ) /* - Groovy can memorize closure results: - More info at: - http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/ - http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize - http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html + Groovy can memorize closure results [1][2][3] */ def cl = {a, b -> sleep(3000) // simulate some time consuming processing @@ -256,9 +272,10 @@ callClosure(3, 4) /* Expando - The Expando class is a dynamic bean so we can add properties and we can add closures as methods to an instance of this class + The Expando class is a dynamic bean so we can add properties and we can add + closures as methods to an instance of this class - Reference: http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html + http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html */ def user = new Expando(name:"Roberto") assert 'Roberto' == user.name @@ -310,7 +327,8 @@ assertEquals "boo", f.boo /* TypeChecked and CompileStatic - Groovy, by nature, is and will always be a dynamic language but it supports typechecked and compilestatic + Groovy, by nature, is and will always be a dynamic language but it supports + typechecked and compilestatic More info: http://www.infoq.com/articles/new-groovy-20 */ @@ -373,7 +391,9 @@ Join a [Groovy user group](http://groovy.codehaus.org/User+Groups) * [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do) - +[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/ +[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize +[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html 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!")) } ``` -- cgit v1.2.3