Golang intro
2013, Michelberger Tamás
Kir-Dev
- Bemutatkozás
- Prezentáció céla
- nem a szintaxisba való bevezetés
- inkább a nyelvben rejlő lehetőségek megmutatása
Tartalom
Történet
Szintaxis
OO
Goroutine-ok
Runtime
Google
Robert Griesemer
Rob Pike
Ken Thompson
Célok
- egyszerűség
- olvashatóság és egyértelműség
- gyors fordítás
- egyszerű kódmegosztás
- C-szerű szintaxis
Szintaxis
- nem teljes áttekintés, csak szemelvények
- nagyon átláható, nem lesz gond a kódrészletek megértésével
- tényleg nagyon erős a C behatás
- http://golang.org/ref/spec
C
Kapcsos zárójel mindenhol
func main() {
fmt.Println("Hello world")
}
C
Hasonló kulcsszavak
int, string, for, if, []byte, //
- már ismert operátorok
- vezérlési szerkezetek
- literálok
- van string beépítve!!!
C
Pointerek
a := 3 // a compiler okos és kitalálja, hogy 'a' int lesz
var b *int = &a
szerencsére elég sokszor nem kell foglalkoznunk azzal, hogy mi pointer és mi nem
majd a metódusoknál látni fogjuk
C
Struktúrák
type Point struct {
X int
Y int
}
p1 := Point{1, 1}
p2 := Point{X: 4, Y: 10}
- nagyjából az egyetlen lehetőség, hogy adatokat egységbe zárjunk
- nincs klasszikus OO
- lehet névtelen is: type #NÉV-vel bármilyen típus újra elnevezhetünk
- "konstruktor"
- sorrendben, akkor minden tag kell
- címkével
Nem C
Nem kell pontosvessző.
Pontosabban a compiler beilleszti helyettünk
a megfelelő helyekre.
vannak helyek ahol lehet és kell is használni
pl if, for esetén két utasítás a fejrészben
Nem C
Névterek
package-ek formájában
minden fájl elején
- C-ből hiányzik a modul/névtér fogalma
- itt ennek egységbezáró szerepe is van
- package a láthatóság határa
- compilation unit
Nem C
Függvények
func add(a, b int) int {
return a + b
}
func div(a, b int) (int, int) {
res := a / b
mod := a % b
return res, mod
}
type HandlerFunc func(ResponseWriter, *Request)
- func kulcsó
- több visszatérési érték, akár nevesített is lehet
- ahogy mindenhol előbb változó név, utána a típus
- func #név(#paraméterek) #visszatérési_érték
- elsőrendű nyelvi elemek, lehet őket passzolgatni paraméterként
Nem C
Szigorú típusosság
var a int32 = 0
var b int64 = a // fordítás idejű hiba
var b int64 = int64(a) // ez már megy
- csak expicit lehet a típusok között castolni
- saját típus és az eredeti típus nem egyezik meg, csak explicit cast
Objektumok osztályok nélkül
- majdnem minden (érték) objektum
- itt kell megjegyezni, hogy minden érték szerint adódik át
- pointerek is
- pont úgy mint C-ben
- kis-nagybetű itt is fontos
Metódusok
Minden általunk deklarált típusra aggathatunk metódusokat.
type Point struct { X,Y int }
func (p Point) Length() float64 {
length := ...
return length
}
- func kulcsszó után a receiver
- lehet pointer vagy sima típus
- itt is másolódik az érték, így csak pointernél lehet a belső változókat piszkálni
- lehet csak func (Point) Print() {} is, de akkor nem érem el a belső értékeket
- klasszikus OO hiányzik: nincs konstruktor, nincsenek statikus metódusok
Interfészek
Polimorfizmus
type Abser interface {
Abs() float64
}
- polimorfizmus elsődleges megnyilvánulása
-
interface{}-be bármi behelyettesíthető, olyan mint Javaban az Object
- elnevezési konvenció
- egy metódust tartalmazó pl Read -> Reader
Interfészek
type myFloat float64
func (f myFloat) Abs() float64 {
if f < 0 {
return -1 * f
}
return f
}
- implicit implementáció
- nem kell ismerni a package-t, amiben deklarálják, akkor is meg lehet valósítani
- egyfajta duck-typing
Öröklés(féle)
A klasszikus öröklés nem létezik Go földön.
Helyette beágyazás van.
Öröklés(féle)
Névtelen mezőként adjuk meg.
type Point struct { X, Y int }
type Circle struct {
Point
R float64
}
c := Circle{Point{0,1}, 2}
- struct és interface is egymásba ágyazható
- hasonló mint a javascriptes prototípusos öröklés
- a beágyazott típus metódusait és mezőit "megkapja" az, akibe ágyazunk
- de felüldefiniálható (metódus és mező is)
- lehet rá hivatkozni azért
- van demo
Goroutine-ok
"Share by communicating"
- konkurrencia vs párhuzamosság!!
- nyelvi támogatás a concurrency primitívekhez
- ne adatokat ossz meg, hanem a "szálak" között passzolgass adatokat
- goroutine: lightwieght thread
- nincs 1-1 mappelés az OS threadekre
- saját ütemező
- szinte ingyen van
- goroutine-ok egymással versenyezve, konkurrensen futnak
Csatornák
Az adatok utaztatásának elsődleges módja.
ch := make(chan int)
ch <- 42
a := <-ch
- típusos
- make beépített függvény, több mindenre is jó
- ch <- adat küldése csatornán keresztül
- ha nincs aki fogadjon, akkor hiba
- blokkol míg ki nem olvassák az értéket
- bufferelés
- <-ch adat olvasása
Csatornák
select
Csatornák switch-case-e
select {
case res := <- done:
// do amazing stuff
case <-timeout:
// handle timeout
}
- több csatorna együttes kezelése
- feltételes választás lehetősége
- eventloop !
- timeout.go
Csatornák
for-range
for t := range time.Tick(1 * time.Second) {
fmt.Println(t.Second())
}
- nem gond ha nem tudjuk mennyi érték jön majd a csatornán
- for-range a go foreach loopja, slice, tömb, map iterálás
- tick.go
- egyszerű számláló.
Runtime
- mini vm (~jvm, clr)
- összehasonlításként: normális vm vs linux konténer
Natív, de mégsem annyira
Valóban natív binárissá fordul, de közben a runtime
mindig ott van a háttérben.
-rwxrwxr-x 1 tomi tomi 411K Nov 27 00:38 blank
-rwxrwxr-x 1 tomi tomi 1.5M Nov 27 00:42 helloworld
GC
Mark-and-sweep
- nem kell törödőni a memória menedzsmenttel
- többszálúságnál nehéz lenne követni, hogy kit mikor lehet felszabadítani
- interfészeknek nem kell törődnie a memória modellel
- 2 fázis:
- megjelöl (naív: bejárja az elérhető objektum teret és megjelöli a még használtakat)
- majd takarít
Reflection
Futásidőben elérhetőek extra információk a típusokról.
Goroutine-ok
- Green threads.
- A runtime intézi a goroutine-ok ütemezését.
- Nincs egy-egy leképzés OS szálakra.