Programmeren in Go: verschil tussen versies
Verwijderde inhoud Toegevoegde inhoud
Bijna klaar |
Zo goed als klaar Label: Herhaalde karakters |
||
Regel 1:
Zo goed als klaar! Hulp gewenst bij formatting pagina.
PDF : http://commons.wikimedia.org/wiki/File:Een_introductie_in_Go_(1).pdf
Auteur: Daniël Heres
Datum: Januari 2010
'''3,2,1 Go!'''
"Weer een nieuwe taal
Deze gids is gemaakt voor mensen die al wat programmeerervaring hebben en snel basisconcepten van deze nieuwe taal willen leren.
'''Commentaar'''
Commentaar is hetzelfde als veel andere talen.
<pre>
/* Dit is commentaar
over meerdere
regels */
// Commentaar voor één regel
</pre>
'''Pakketten'''
De eerste regel van Go moet een pakketnaam beschrijven. In een Go project moet er minstens één pakket zijn met de naam main en die moet een functie met de naam "main" bevatten.
<pre>
package kabouters // Andere pakketten in project kunnen dit kabouterpakket importeren
Regel 34 ⟶ 33:
import "./mutsen" // Pakket beschikbaar in map
</pre>
'''Variabelen en constanten'''
Het declareren van variabelen en typen gaat in Go behoorlijk anders dan in de meeste talen. Typen worden achteraf gedeclareerd, na de namen. Dit is duidelijk te zien in het volgende voorbeeld.
<pre>
var a int // Variabele a heeft type int. Let op: een puntkomma als einde voor een statement is voor Go niet noodzakelijk (mag wel)
Regel 45 ⟶ 46:
const r int = 5 // e is een constante
var f = 5 //
var g string = "Go go go!"
Regel 54 ⟶ 55:
j int32 = 45;
k, l, m = "GOOG", 43, 1.0
) // Gebruik van haakjes is heel handig bij declareren van veel variabelen, puntkomma's zijn verplicht als scheidingsteken! Haakjes kunnen ook bij sleutelwoorden const en type gebruikt worden
const (
Regel 69 ⟶ 70:
p, q, r := 5.7, 100, "Kort"
}
</pre>
Regel 75 ⟶ 76:
De laatste constanten kunnen bijvoorbeeld door een programma verkleind worden tot
<pre>
const(a,b,c,d,e,f=9,7,10,8,5,2)
</pre>
Dat is natuurlijk geen toeval. Grote programma's moeten zo snel mogelijk over een netwerk verstuurd worden, daar helpt een korte notatie natuurlijk goed bij! Hier zal ook bij de volgende concepten goed over nagedacht zijn!
Regel 82 ⟶ 84:
Tot slot, de numerieke types zijn:
int uint float
int8 uint8 of byte
int16 uint16
int32 uint32 float32
int64 uint64 float64
'''Assignments'''
Laten we meteen maar met een paar voorbeelden beginnen!
<pre>
a = x
b, c = functie1(), 5 // Meerdere assignments, we zien
d, e = e, d // Wisselen van variabelen! Hiervoor zijn bij minder expressieve talen drie regels voor nodig
</pre>
If
Voor
<pre>
import "fmt" // importeert pakket fmt
func main() {
if x<a {
klein()
} else if x>a { // Let op, else en else if moeten op zelfde regel als sluitende accolade!
groot()
Regel 121 ⟶ 126:
}
</pre>
Operators
Voorrang
4 == != < <= > >=
3 <- (Deze operator wordt gebruikt voor communicatie tussen Goroutines)
2 &&
1 ||
'''For'''
Een for loop gebruikt ook geen haakjes. Een for loop heeft twee verschillende modussen: één met één element en één met drie elementen.
<pre>
for a<5 {} // Dit is gelijk aan een while statement in andere talen
Regel 144 ⟶ 152:
for a:=0; ; a++{} // while(true) en een counter!
for a:=0; a<10; a++ {} // Een gewone for-
for i
</pre>
'''Switch'''
Switches zijn grotendeels gelijk aan andere talen met een paar belangrijke verschillen: alle types kunnen gebruikt worden en er is geen break nodig (waarmee vaak fouten worden gemaakt), het switch statement stopt standaard zodra er een kloppende voorwaarde is.
<pre>
switch f(10){
case 100: Print("Vertienvoudigd!")
Regel 162 ⟶ 171:
switch f:=f(10);{ // Je kan ook meerdere variabelen of declareren!
case f>100: Print("Erg groot")
case f>10: Print("Aardig groot") fallthrough
case f==20: Print("Aardig groot en ook nog 20!")
}
</pre>
'''Functies'''
Kenmerkend voor Go zijn de notatie van parameters en de mogelijkheid om meerdere waardes te "returnen". Een functie wordt gedeclareerd met "func".
<pre>
/* Meerdere waardes kunnen voor het registreren van fouten gebruikt worden
*/
Regel 179 ⟶ 188:
}
func Konijn(wortels int) (genoeg bool) { // Als je parameters benoemt kun je ze gebruiken
if wortels > 10 { genoeg = true
return genoeg
}
func Konijn(wortels int) (genoeg bool) {
if wortels > 10 { genoeg = true
return // genoeg wordt "gereturned", kleiner dan
}
func FunctieInFunctie(i int) (int) (
g := func(j int) (int) { // Bij aanroepen functie Konijn function call Konijn() in body zetten
h := j * i + 1;
return h
Regel 200 ⟶ 211:
x = x +5
}
</pre>
'''Defer'''
Defer is een statement die als functie heeft om de executie van een statement te verplaatsen naar het einde van een functie. De volgorde van executie is LIFO, het laatste statement wordt als eerste uitgevoerd. Dit kan handig zijn om meerdere functies te groeperen, bijvoorbeeld bij IO.
<pre>
func
o := file.Open(element)
defer o.Close() // Verplaatst zich naar onderen
p := o.
// Nu pas!
return p
}
</pre>
'''Arrays'''
<pre>
var x = [4]int{2, 8, 19, 30} // Maak een array met lengte 4 en waardes 2, 8, 19 en 30
var y = [4]int{2, 9} // Array met lengte 4, met waardes 2, 9, 0, 0
Regel 230 ⟶ 244:
for i := range x {
fmt.Print(i) // 0, 1, 2, 3
fmt.Print("\n")
}
for _, j := range x { // Een array heeft keys (index) en waardes, indien je keys niet nodig hebt gebruik je een laag streepje om alleen de waardes op te vragen!
fmt.Print(j) // 2, 8, 19, 30
Regel 248 ⟶ 262:
}
</pre>
'''Slices'''
Slices zijn vrij uniek voor Go. Slices zijn eigenlijk verwijzingen naar arrays met een variabele lengte. Omdat slices verwijzingen zijn (alle instanties die aangemaakt zijn met functie "make()") hoef je niet met pointers te werken.
<pre>
var a = []int{} // Integer slice
var b = []string{} // String slice
Regel 266 ⟶ 281:
return sl
}
</pre>
'''Methodes'''
<pre>
func (o *ObjectType) FunctieNaam() (aanroep int) returnwaarde int {
}
// Dus
func (v *Vector2D) Optellen
v.x = v.x + w.x
v.y = v.y + w.y
}
</pre>
'''Types'''
In Go kan je verschillende soorten types aanmaken. Types zijn niet hetzelfde als types in andere programmeertalen.
Soort type Eigenschap
Type van een al bestaand type Nieuwe naam voor type, mogelijk uitbreiden met methodes.
Interface Beschrijft
Struct Vormt structuur van geheugen (velden en methoden). Lijkt een beetje op een klasse uit andere talen maar heeft niet precies dezelfde functie.
Je kan instanties van dit type aanmaken.
''Type van een type''
<pre>
type Dag int
type Kracht float
type Mensen []string
// Uitbreiden met methodes
func (d Dag) DagNaarJaar() int {
return d / 365 + 1
}
func (k Kracht) KrachtNaarGewichtAarde() float {
return k / 9.81
}
</pre>
''Interface''
<pre>
type Honden interface { // Specificatie interface
Rennen(h *Hond) // *Voer betekent verwijzing naar object met type Voer
Regel 305 ⟶ 334:
}
func (h *Hond) Rennen() { //
// *Hond is recievertype, kan voor elk type
h.ren = true
}
func (h *Hond) Eten(v Voer) bool { // Nog een
if (h.ren || v == PrutUitBlik) {
return false
Regel 316 ⟶ 345:
return true
}
</pre>
''Struct''
<pre>
type Hond struct {
x,y int
Regel 338 ⟶ 368:
fmt.Print(monty.Eten(Brokken)) // Wat wordt dit?
}
</pre>
'''Goroutines'''
Programmeurs vinden concurrency vaak lastig. Go heeft het uitvoeren van meerdere code in dezelfde geheugenruimte in de taal ingebouwd om het een stukje makkelijker te maken. Een Goroutine wordt gestart door het sleutelwoord "go".
<pre>
func zegHoi() {
fmt.Print("Hoi")
Regel 352 ⟶ 383:
time.Sleep(1000000000) // Nanoseconden
}
</pre>
We kunnen ook een anonieme functie gebruiken.
<pre>
func main() {
go func() {
Regel 362 ⟶ 395:
time.Sleep(1000000000)
}
</pre>
Buiten dat het geen zin heeft om een aparte Goroutine te openen om naar een console te schrijven is er iets anders: er is helemaal geen garantie dat de Goroutines
Daarvoor zijn Channels in het leven geroepen.
'''Channels'''
Channels worden gebruikt om te wachten en om informatie uit te wisselen, bijvoorbeeld over de status van een berekening.
<pre>
var quit = make(chan bool) // Maakt een channel met communicatietype bool
Regel 381 ⟶ 416:
fmt.Print(x) // Geeft output true in console
}
</pre>
We kunnen dat zo vaak als we willen communiceren met een Goroutine.
<pre>
var comm = make(chan int)
Regel 402 ⟶ 438:
}
}
</pre>
We kunnen meerdere Goroutines parallel uitvoeren. Om meerdere channels aan te maken gebruiken we
channelnaam := make(chan Type, aantal). De volgende code simuleert een hond met 4 koppen die elk 1 seconde nodig hebben om een brok op te eten.
<pre>
package main
import "fmt"
import "time"
const Cores = 4
Regel 415 ⟶ 457:
}
func EetBrok(h *Hond
time.Sleep(1000000000)
h.stuks = h.stuks - 1
fmt.Printf("Brok opgegeten, nog %d
c<-true
}
func (h *Hond) EetBrokken(brokken int) {
if h.ren { // Als hond niet rent kan hond geen brok eten.
return
}
h.stuks = brokken
c := make(chan bool, Cores)
j := brokken / Cores
for k:=0; k<j; k++ { // We willen (brokken / Cores) keer met 4 koppen eten
for i:= 0; i<Cores; i++ { // We vullen 4 channels
go
}
for i:= 0; i<Cores; i++ { // We wachten op de 4 channels
<-c
}
}
nogtedoen := h.stuks // Als aantal brokken niet te delen is door 4 moeten we nog een aantal brokken eten
if nogtedoen==0 {return}
for i:=0; i<nogtedoen; i++ {
go
}
for i:= 0; i<nogtedoen; i++ {
<-c
}
}
func main(){
rex := &Hond{7, 9,
rex.EetBrokken(50)
}
</pre>
'''Select'''
Select is een statement dat op een vergelijkbare manier als switch gebruikt kan worden maar alleen voor communicatie van channels wordt gebruikt.
<pre>
package main
import "rand"
import "fmt"
import "time"
type Koe struct {
n int // Koeiennummer
gras int // De koe eet soms gras en soms niet.
}
func GrazendeKoe(n int, chan1 chan *Koe, chan2 chan *Koe) {
koe := &Koe{n, 0}
r := rand.New(rand.NewSource(time.Nanoseconds())) // Nanoseconds is een seed
var j int
for {
j = r.Intn(2) // Waarde tussen 0 en 1
koe.gras = j
if j==0 {
chan1 <- koe
} else {
chan2 <- koe
}
time.Sleep(1000000000)
}
}
func main() {
var k *Koe
chan1 := make(chan *Koe) // Koe loeit naar boer 1
chan2 := make(chan *Koe) // Koe loeit naar boer 2
go GrazendeKoe(1, chan1, chan2)
go GrazendeKoe(2, chan1, chan2)
for {
select {
case k = <- chan1: // Als we een signaal van chan1 krijgen
fmt.Printf("Koe %d, Boer 1, Gras: %d \n", k.n, k.gras)
case k = <- chan2: // Waarde niet opslaan kan door laag streepje
fmt.Printf("Koe %d, Boer 2, Gras: %d \n", k.n, k.gras)
}
}
}
</pre>
|