SlideShare ist ein Scribd-Unternehmen logo
Ein Gopher im Netz
Frank Müller / Loodse GmbH
Vorstellung
• Frank Müller
• Oldenburg
• Baujahr 1965
• Senior Solution Engineer

bei Loodse GmbH
• Im Netz als @themue zu finden
Kurzüberblick
• Go ist langweilig
• Go folgt keinem klaren Paradigma
• Go bietet keine esoterischen Features
• Go bietet nichts wirklich Neues
• Go ist nicht perfekt
• Go beinhaltet Stolpersteine
ABER
• Go ist einfach (Language Specification nur eine HTML Seite)
• Go bringt eine umfangreiche Bibliothek mit sich
• Go kompiliert sehr schnell in ein Binary
• Go beherrscht Cross-Compiling
• Go verfügt über Garbage Collection
• Go führt sehr schnell aus
• Go ist pragmatisch
–Oscar Wilde
„It’s better to have a permanent income than to be
fascinating.“
Historie
Historie
• Start Ende 2007 aus Frust
• FAQ: „One had to choose either efficient compilation, efficient
execution, or ease of programming; all three were not available
in the same mainstream language.“
• Beginn der Entwicklung Mitte 2008
• Erste öffentliche Vorversion im November 2009
• Version 1.0 im März 2012
–Rob Pike
„Go aims to combine the safety and performance of a
statically typed compiled language with the
expressiveness and convenience of a dynamically typed
interpreted language.
It also aims to be suitable for modern systems – large
scale – programming.“
Das Team
• Rob Pike
• Ken Thompson
• Robert Griesemer
• Russ Cox
• Ian Lance Taylor
• Und weitere ...
Keine Unbekannten
• Ken Thompson — Multics, Unix, B, Plan 9, ed, UTF-8, etc. sowie
Turing Award
• Rob Pike — Unix, Plan 9, Inferno, Limbo, UTF-8, etc.
• Robert Griesemer — Strongtalk, Java HotSpot VM, V8
JavaScript Engine
Fortschritt
• 2014 wurde der der Gopher das Maskottchen von Go;
entworfen von Renée French, der Ehefrau von Rob Pike
• Alle 6 Monate erscheint ein neues Release
• Aktuell Version 1.12.5
• Versprechen der Sprachkompatibilität gleicher Hauptversionen
• Go 2 in Diskussion
Werkzeuge
Drei Binaries
• go — Wichtigstes Werkzeug mit vielen Subcommands
• gofmt — Einheitliche Formatierung der Go Quellen
• godoc — Generierung von Dokumentation aus Kommentaren
go Subcommands (Auszug)
• build — Compiling der Quellen
• fmt — Formattierung der Quellen
• get — Packages herunterladen und installieren
• install — Compiling und Installation der Quellen
• mod — Verwaltung von Modulen
• test — Durchführung der Unit Tests
• vet — Bericht über gängige Fehler
go mod Subcommands (Auszug)
• download — Download von Modulen in lokalen Cache
• init — Initialisierung eines Moduls im aktuellen Verzeichnis
• tidy — Bereinigung der Abhängigkeiten
• vendor — Vendorize von Abhängigkeiten
• why — Erläuterung von Abhängigkeiten
Die Sprache Go
Orientierung in Packages
• Code immer in Packages
• Ein oder mehrere Dateien pro Package in einem Verzeichnis
• Sonderrollen
• main wird zu ausführbarem Programm
• <name>_test wird zu Unit Test von Package <name>
• Packages lassen sich hierarchisch schachteln
// main wird zu Programm mit dem Namen des Verzeichnisses.
package main
// Einstieg in das Programm.
func main() {
println("Hello, World!")
}
Import von Packages
• Import als erste Anweisung nach dem Package Statement
• Externe Packages enthalten Domain und Pfad
• Eigene Domains mit Code auf z.B. GitHub sind via Meta Tags in
einem lokalen HTML-Dokument ebenfalls möglich
• Package-Name als Präfix für Namensräume
• Alias kann gegen Namensgleichheit gesetzt werden
• Export durch Großschreibung, sonst package private
package info
import (
"fmt"
"github.com/moby/moby/volume"
myvolume "github.com/myname/myproject/volume"
)
func Info() string {
return fmt.Sprintf("name %v / size %v",
volume.DefaultDriverName, myvolume.DefaultSize())
}
Funktionen
• Schlüsselwort func
• Mit Namen, anonym oder als Methode eigener Typen
• Beliebige Anzahl Parameter, letzter kann variadisch sein
• Beliebige Anzahl Rückgabewerte ohne und mit Namen
• Rückgabe mit Schlüsselwort return
// Mul multipliziert f mit einer beliebigen Anzahl
// Integer.
func Mul(f int, vs ...int) int {
r := f
for _, v := range vs {
r *= v
}
return r
}
// Div dividiert f ganzzahlig durch eine beliebige Anzahl
// Integer.
func Div(f int, vs ...int) (int, error) {
r := f
for _, v := range vs {
if v == 0 {
return 0, errors.New("division by zero")
}
r /= v
}
return r, nil
}
// Server ist ein Typ mit privaten Feldern.
type Server struct {
port int
...
}
// Option ist eine Funktion, die auf einem Server operiert.
type Option func(s *Server)
// Port liefert eine Option zum Setzen des Felds port
// zurück.
func Port(port int) Option {
return func(s *Server) {
s.port = port
}
}
// New erzeugt einen Server. Optionen sind ... optional. ;)
func New(opts ...Option) *Server {
s := &Server{
port: 12345, // Standardwert.
...
}
for _, opt := range opts {
opt(s)
}
return s
}
Typenlehre
Einfache Typen
• int / int8 / int16 / int32 / rune / int64
• uint / uint8 / byte / uint16 / uint32 / uint64
• float32 / float64
• complex64 / complex128
• bool
• string
Zusammengesetzte Typen
• Arrays und Slices
• Maps
• Structs
• Funktionen
• Interfaces
• Error
• Channel
type StringProducer func() []string
func (sp StringProducer) Len() int {
return len(sp())
}
// Sizer definiert in meinem Package, was ich von einem
// Typ benötige.
type Sizer interface {
Len() int
}
func SizePrinter(sizer Sizer) { ... }
type Honk interface {
Honk() string
}
// Car bettet Honk ein, geht mit Structs und Interfaces.
type Car struct {
Honk
motor *Motor
...
}
myCar.Honk()
// Handler in Package net/http definiert einen Handler für
// Web Requests.
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
// ListenAndServe startet den Server mit einem Handler.
func ListenAndServe(addr string, handler Handler) error
// HandlerFunc vereinfach den Handler zu nur einer Funktion.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP implementiert den Handler und führt nur die
// Handler-Funktion aus.
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
// ServeMux verteilt auf Handler nach Pfaden.
type ServeMux struct {
...
}
func (mux *ServeMux) Handle(pattern string, handler Handler) {
...
}
// ServeHTTP implementiert Handler.
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
...
}
Von einfachem Interface zu mehr
• Multiplexer für HTTP Methoden
• Multiplexer für Schachtelung bei RESTful APIs
• Schachtelung für Trennung von Authentisierung/Autorisierung
via JSON Web Tokens o.ä.
Variablen explizit und implizit
• Mit Deklaration via var oder mit Zuweisung durch :=
• Typisierung explizit oder implizit
• var kennt beides, := ist immer implizit
• Zuweisung mit =
var s1 string // Deklaration
s1 = "Hello" // Zuweisung
var s2 string = "World" // Explizit mit Zuweisung
var s3 = s1 + ", " + s2 // Implizit mit Zuweisung
s4 := s3 + "!" // Deklaration implizit mit
// Zuweisung
Kontrolle behalten
Bedingungen
• Mit if oder switch für logische Bedingungen
• Mit select für Channel
• switch und select kennen default an beliebiger Stelle
• break nicht notwendig
• switch verfügt über fallthrough für die Ausführung der
Folgebedingung
if x > y {
x, y = y, x
}
if myFunctionReturnsTrue() {
fmt.Println("Juchu!")
} else {
fmt.Println("Schade")
}
switch x {
case 1, 2, 3:
fmt.Println("1 bis 3")
// Verpönte Weiterverarbeitung!
fallthrough
case 4, 5, 6:
fmt.Println("4 bis 6")
default:
fmt.Println("Keine Ahnung")
}
// Abarbeitung von oben nach unten, aber default immer nur
// wenn nichts passt.
switch {
case x < 0:
fmt.Println("Kleiner als 0")
default:
fmt.Println("Ha! Genau 0")
case x > 0:
fmt.Println("Größer als 0")
}
select {
case <-ctx.Done()
return ctx.Err()
case job := <-jobs:
if err := job(); err != nil {
log.Printf("job failed: %v", err)
}
case <-time.Tick(5 * time.Second):
log.Printf("I'm waiting ...")
}
Schleifen
• Schlüsselwort for
• Verschiedene Formen der Bedingungen
• Vorzeitige Fortsetzung über continue
• Vorzeitiges Verlassen über break
• Label für geschachtelte Schleifen
• Arrays, Slices, Maps und Channel können mit range iteriert
werden
for {
...
if shallLeave {
break
}
}
i := 0
for i < 2019 {
...
i++
}
for i := 0; i < 2019; i++ {
if i % 2 == 0 {
continue
}
...
}
visitors := visitorsByConference("JAX 2019")
for i, visitor := range visitors {
fmt.Printf("Besucher %d ist %sn", i, visitor.Name)
}
Nebenläufigkeit
Nebenläufigkeit
• Leichtgewichtige Funktionen (Goroutinen) im Thread Pool
• Schnelle Kontextwechsel
• Kommunikation über typisierte Channel
• Abfrage mehrerer Channel gleichzeitig über select
• Start mit Schlüsselwort go
• Gibt keine ID o.ä. zurück
–Rob Pike
„In programming, concurrency is the composition of
independently executing processes, while parallelism is
the simultaneous execution of (possibly related)
computations.
Concurrency is about dealing with lots of things at once.
Parallelism is about doing lots of things at once.“
Muster
• Einfacher Funktionsablauf im Hintergrund
• „Mach mal.“
• Dito mit Rückgabe eines Ergebnisses über einen Channel
• „Mach mal und bring mir dann das Ergebnis.“
• Kontinuierlicher Empfang zu verarbeitender Daten
• „Kümmere dich um alle meine Aufträge.“
• Dito mit serialisiertem Zugriff auf einen privaten Zustand
• „Sei mein schlauer Kollege.“
Client / Server
Client
Client
Client
Server
Aufgabenverteilung
Client
Client
Client
Dispatcher
Worker
Worker
Worker
Map / Reduce
Map
Reduce
Map
Map
Reduce
Map
Reduce
Netze von Goroutinen
Goroutine Goroutine Goroutine Goroutine
Goroutine Goroutine Goroutine
Goroutine Goroutine
Server
als
Beispiel
type Op func()
// Calc ist ein Taschenrechner mit einem Wert als Zustand.
type Calc struct {
cancel context.CancelFunc
ops chan Op
value float64
}
func New(ctx cancel.Context) *Calc {
c := &Calc{
ops: make(chan Op, 1),
value: 0.0,
}
ctx, c.cancel = context.WithCancel(ctx)
go c.backend(ctx)
return c
}
func (c *Calc) Stop() {
c.cancel()
}
func (c *Calc) Add(v float64) (r float64) {
wait := make(chan struct{})
c.ops <- func() {
c.value += v
r = c.value
close(wait)
log.Printf("calc added %f, new value is %f", v, r)
}
<-wait
return
}
func (c *Calc) Div(v float64) (r float64, err error) {
if v == 0 { return 0.0, errors.New("divide by zero") }
wait := make(chan struct{})
c.ops <- func() {
c.value /= v
r = c.value
close(wait)
log.Printf("calc divided %f, new value is %f", v, r)
}
<-wait
return
}
func (c *Calc) backend(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
case op := <-c.ops:
op()
}
}
}
Weiteres
Aufschieben
• Funktionen können im Ablauf mit defer gestapelt werden
• Werden rückwärts beim Verlassen der umgebenden Funktion
ausgeführt
• Praktisch für Aufräumarbeiten, zum Beispiel Schließen
geöffneter Dateien
file, err := ioutil.TempFile("/tmp", "jax2019")
if err != nil {
return fmt.Errorf("failed to open temp file: %v", err)
}
defer file.Close()
writer := bufio.NewWriter(file)
defer writer.Flush()
writer.WriteString("JAX 2019n")
writer.WriteString("Ein Gopher im Netzn")
Fehlerbehandlung
• Keine Exceptions
• Fehlertyp error als letzter Rückgabewert
• Interface mit Methode Error() string
• panic() für echte Ausnahmesituationen
• Kann mit recover() aufgefangen werden
func CanBreakHard(x int) (err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
}()
...
if veryBadCondition {
panic("have a very, yes, very, very bad condition")
}
return nil
}
Bibliothek
Daten
• Archivierung (tar, zip)
• Komprimierung (bzip2, flate, gzip, lzw, zlib)
• Encoding (ASN.1, CSV, JSON, XML)
• Strings, Text, reguläre Ausdrücke
• Text Templates
• Time
• Unicode
Netz
• Crypto (AES, Cipher, ECDSA, HMAC, RSA, SHA512, TLS)
• Netzwerk
• HTTP Client und Server
• HTML Templates
• JSON-RPC
• SMTP
Und vieles mehr ...
• I/O
• SQL Datenbanken
• Synchronisation (Mutex, Once, WaitGroup), Context
• Images
• Reflection
• Unit Tests
Zusammenfassung
Paradigmenmix ohne Overload
• Sequentielle Abfolge von Anweisungen ➟ imperativ
• Funktionstypen, Closures ➟ funktional
• Methoden, Interfaces, Komposition ➟ objekt-orientiert
• Goroutinen, Channels ➟ nebenläufig
Fast wie Scripting
• Einfache Syntax
• Leichtgewichtiges Typenmodell
• Wenige Schlüsselworte
• Schnelle Kompilation erlaubt schnelle Tests
• Aber: Manchmal mehrere Lösungswege möglich
• Nutzung etablierter Konventionen hilft
Einfache Nebenläufigkeit
• Prinzipiell nur Funktionen
• Flexible Kommunikation
• Weitere Hilfen zur Synchronisation
• Aber: Kein Schutz vor gleichzeitigem Zugriff auf Variablen
• Aber: Kein Schutz vor Locks und Races
• Tools helfen, ansonsten Verantwortung des Entwicklers
Vielen Dank

Weitere ähnliche Inhalte

PDF
Devs@Home - Einführung in Go
PDF
C Sharp Einfuehrung Teil 1
PDF
An Introduction to Ruby
PDF
DevOpsCon - Verteilte Entwicklung in Go
PDF
C Sharp Einfuehrung Teil 2
PDF
Spaß an der Nebenläufigkeit
PDF
Einführung in .NET mit C#
PPT
Die freie Programmiersprache Python
Devs@Home - Einführung in Go
C Sharp Einfuehrung Teil 1
An Introduction to Ruby
DevOpsCon - Verteilte Entwicklung in Go
C Sharp Einfuehrung Teil 2
Spaß an der Nebenläufigkeit
Einführung in .NET mit C#
Die freie Programmiersprache Python

Was ist angesagt? (20)

PPT
Übersicht Skriptsprachen
PDF
Architektur einer Eclipse DLTK IDE für Clojure
PDF
Go - Googles Sprache für skalierbare Systeme
KEY
Metaprogrammierung mit Ruby
PDF
Php Schulung
PDF
Infrastructure as Code - BaselOne 17
PDF
Web Entwicklung mit PHP - Teil 2
PDF
Web Entwicklung mit PHP - Teil 1
PDF
Cloud Provisioning mit Juju
PDF
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
PDF
Referat T13 Javadoc
PDF
Einführung in die funktionale Programmierung mit Clojure
PDF
PDF
Ruby is Magic - Episode #7: Closures
PDF
Scalaz introduction for Java programmers
PDF
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
PDF
Verteilte Anwendungen bei Azure mit Docker und Kubernetes
PPT
Interprozesskommunikation mit PHP
PDF
Check cisco voice
PDF
TMQL tutorial - part 4
Übersicht Skriptsprachen
Architektur einer Eclipse DLTK IDE für Clojure
Go - Googles Sprache für skalierbare Systeme
Metaprogrammierung mit Ruby
Php Schulung
Infrastructure as Code - BaselOne 17
Web Entwicklung mit PHP - Teil 2
Web Entwicklung mit PHP - Teil 1
Cloud Provisioning mit Juju
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
Referat T13 Javadoc
Einführung in die funktionale Programmierung mit Clojure
Ruby is Magic - Episode #7: Closures
Scalaz introduction for Java programmers
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
Verteilte Anwendungen bei Azure mit Docker und Kubernetes
Interprozesskommunikation mit PHP
Check cisco voice
TMQL tutorial - part 4
Anzeige

Ähnlich wie Ein Gopher im Netz (20)

PDF
Java und Go im Vergleich
PDF
Ruby und Rails für .NET Entwickler
PDF
Vagrant - Einführung & Verwendung
PDF
Skalierbare Anwendungen mit Google Go
PDF
Javascript done right
PDF
Schweine latein-vortrag
PDF
Docker und Kubernetes Patterns & Anti-Patterns
PDF
Docker und Kubernetes Patterns & Anti-Patterns
PDF
JavaScript für Java-Entwickler W-JAX 2013
PDF
Unixkurs 06 - Shellskripte
PDF
JSF vs. GWT? JSF und GWT!
PDF
FMK2022 Neue Programmiertechniken von Adam Augusting
PPTX
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
PDF
FMK 2013 Konstrukte diverser Programmiersprachen in FileMaker nachgebaut, Tho...
PPTX
Creasoft - Windows powershell
PDF
Back to the future - Plone 5.2 und Python 3 Migration am Beispiel Onkopedia
PDF
FLOW3-Workshop F3X12
PPTX
Vagrant, Puppet, Docker für Entwickler und Architekten
PDF
GWT – Google Web Toolkit in der Praxis
PDF
Ist GraphQL das bessere REST
Java und Go im Vergleich
Ruby und Rails für .NET Entwickler
Vagrant - Einführung & Verwendung
Skalierbare Anwendungen mit Google Go
Javascript done right
Schweine latein-vortrag
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
JavaScript für Java-Entwickler W-JAX 2013
Unixkurs 06 - Shellskripte
JSF vs. GWT? JSF und GWT!
FMK2022 Neue Programmiertechniken von Adam Augusting
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
FMK 2013 Konstrukte diverser Programmiersprachen in FileMaker nachgebaut, Tho...
Creasoft - Windows powershell
Back to the future - Plone 5.2 und Python 3 Migration am Beispiel Onkopedia
FLOW3-Workshop F3X12
Vagrant, Puppet, Docker für Entwickler und Architekten
GWT – Google Web Toolkit in der Praxis
Ist GraphQL das bessere REST
Anzeige

Mehr von Frank Müller (20)

PDF
IT-Tage 2024: Philosophie in der Software-Architektur
PDF
JAX 2023 - Cloud Provider APIs
PDF
JAX 2023 - Generics in Go
PDF
Let The Computer Do It
PDF
Concurrency with Go
PDF
2021 OOP - Kubernetes Operatoren
PDF
Fun with functions
PDF
Blockchains - Mehr als nur digitale Währungen
PDF
Juju - Scalable Software with Google Go
PDF
RESTful Web Applications with Google Go
PDF
Clouds, leicht beherrschbar
PDF
WTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
PDF
Juju - Google Go in a scalable Environment
PDF
OOP 2013 - Weltweite Entwicklung von Open Source Software
KEY
Beauty and Power of Go
PDF
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
PDF
Go to the Cloud
KEY
On Event-Driven Architecture
KEY
Google Go - Good artists borrow, great artists steal.
KEY
Agility And The Way To SOA
IT-Tage 2024: Philosophie in der Software-Architektur
JAX 2023 - Cloud Provider APIs
JAX 2023 - Generics in Go
Let The Computer Do It
Concurrency with Go
2021 OOP - Kubernetes Operatoren
Fun with functions
Blockchains - Mehr als nur digitale Währungen
Juju - Scalable Software with Google Go
RESTful Web Applications with Google Go
Clouds, leicht beherrschbar
WTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
Juju - Google Go in a scalable Environment
OOP 2013 - Weltweite Entwicklung von Open Source Software
Beauty and Power of Go
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
Go to the Cloud
On Event-Driven Architecture
Google Go - Good artists borrow, great artists steal.
Agility And The Way To SOA

Ein Gopher im Netz

  • 1. Ein Gopher im Netz Frank Müller / Loodse GmbH
  • 2. Vorstellung • Frank Müller • Oldenburg • Baujahr 1965 • Senior Solution Engineer
 bei Loodse GmbH • Im Netz als @themue zu finden
  • 4. • Go ist langweilig • Go folgt keinem klaren Paradigma • Go bietet keine esoterischen Features • Go bietet nichts wirklich Neues • Go ist nicht perfekt • Go beinhaltet Stolpersteine
  • 5. ABER • Go ist einfach (Language Specification nur eine HTML Seite) • Go bringt eine umfangreiche Bibliothek mit sich • Go kompiliert sehr schnell in ein Binary • Go beherrscht Cross-Compiling • Go verfügt über Garbage Collection • Go führt sehr schnell aus • Go ist pragmatisch
  • 6. –Oscar Wilde „It’s better to have a permanent income than to be fascinating.“
  • 8. Historie • Start Ende 2007 aus Frust • FAQ: „One had to choose either efficient compilation, efficient execution, or ease of programming; all three were not available in the same mainstream language.“ • Beginn der Entwicklung Mitte 2008 • Erste öffentliche Vorversion im November 2009 • Version 1.0 im März 2012
  • 9. –Rob Pike „Go aims to combine the safety and performance of a statically typed compiled language with the expressiveness and convenience of a dynamically typed interpreted language. It also aims to be suitable for modern systems – large scale – programming.“
  • 10. Das Team • Rob Pike • Ken Thompson • Robert Griesemer • Russ Cox • Ian Lance Taylor • Und weitere ...
  • 11. Keine Unbekannten • Ken Thompson — Multics, Unix, B, Plan 9, ed, UTF-8, etc. sowie Turing Award • Rob Pike — Unix, Plan 9, Inferno, Limbo, UTF-8, etc. • Robert Griesemer — Strongtalk, Java HotSpot VM, V8 JavaScript Engine
  • 12. Fortschritt • 2014 wurde der der Gopher das Maskottchen von Go; entworfen von Renée French, der Ehefrau von Rob Pike • Alle 6 Monate erscheint ein neues Release • Aktuell Version 1.12.5 • Versprechen der Sprachkompatibilität gleicher Hauptversionen • Go 2 in Diskussion
  • 14. Drei Binaries • go — Wichtigstes Werkzeug mit vielen Subcommands • gofmt — Einheitliche Formatierung der Go Quellen • godoc — Generierung von Dokumentation aus Kommentaren
  • 15. go Subcommands (Auszug) • build — Compiling der Quellen • fmt — Formattierung der Quellen • get — Packages herunterladen und installieren • install — Compiling und Installation der Quellen • mod — Verwaltung von Modulen • test — Durchführung der Unit Tests • vet — Bericht über gängige Fehler
  • 16. go mod Subcommands (Auszug) • download — Download von Modulen in lokalen Cache • init — Initialisierung eines Moduls im aktuellen Verzeichnis • tidy — Bereinigung der Abhängigkeiten • vendor — Vendorize von Abhängigkeiten • why — Erläuterung von Abhängigkeiten
  • 18. Orientierung in Packages • Code immer in Packages • Ein oder mehrere Dateien pro Package in einem Verzeichnis • Sonderrollen • main wird zu ausführbarem Programm • <name>_test wird zu Unit Test von Package <name> • Packages lassen sich hierarchisch schachteln
  • 19. // main wird zu Programm mit dem Namen des Verzeichnisses. package main // Einstieg in das Programm. func main() { println("Hello, World!") }
  • 20. Import von Packages • Import als erste Anweisung nach dem Package Statement • Externe Packages enthalten Domain und Pfad • Eigene Domains mit Code auf z.B. GitHub sind via Meta Tags in einem lokalen HTML-Dokument ebenfalls möglich • Package-Name als Präfix für Namensräume • Alias kann gegen Namensgleichheit gesetzt werden • Export durch Großschreibung, sonst package private
  • 21. package info import ( "fmt" "github.com/moby/moby/volume" myvolume "github.com/myname/myproject/volume" ) func Info() string { return fmt.Sprintf("name %v / size %v", volume.DefaultDriverName, myvolume.DefaultSize()) }
  • 22. Funktionen • Schlüsselwort func • Mit Namen, anonym oder als Methode eigener Typen • Beliebige Anzahl Parameter, letzter kann variadisch sein • Beliebige Anzahl Rückgabewerte ohne und mit Namen • Rückgabe mit Schlüsselwort return
  • 23. // Mul multipliziert f mit einer beliebigen Anzahl // Integer. func Mul(f int, vs ...int) int { r := f for _, v := range vs { r *= v } return r }
  • 24. // Div dividiert f ganzzahlig durch eine beliebige Anzahl // Integer. func Div(f int, vs ...int) (int, error) { r := f for _, v := range vs { if v == 0 { return 0, errors.New("division by zero") } r /= v } return r, nil }
  • 25. // Server ist ein Typ mit privaten Feldern. type Server struct { port int ... } // Option ist eine Funktion, die auf einem Server operiert. type Option func(s *Server)
  • 26. // Port liefert eine Option zum Setzen des Felds port // zurück. func Port(port int) Option { return func(s *Server) { s.port = port } }
  • 27. // New erzeugt einen Server. Optionen sind ... optional. ;) func New(opts ...Option) *Server { s := &Server{ port: 12345, // Standardwert. ... } for _, opt := range opts { opt(s) } return s }
  • 29. Einfache Typen • int / int8 / int16 / int32 / rune / int64 • uint / uint8 / byte / uint16 / uint32 / uint64 • float32 / float64 • complex64 / complex128 • bool • string
  • 30. Zusammengesetzte Typen • Arrays und Slices • Maps • Structs • Funktionen • Interfaces • Error • Channel
  • 31. type StringProducer func() []string func (sp StringProducer) Len() int { return len(sp()) } // Sizer definiert in meinem Package, was ich von einem // Typ benötige. type Sizer interface { Len() int } func SizePrinter(sizer Sizer) { ... }
  • 32. type Honk interface { Honk() string } // Car bettet Honk ein, geht mit Structs und Interfaces. type Car struct { Honk motor *Motor ... } myCar.Honk()
  • 33. // Handler in Package net/http definiert einen Handler für // Web Requests. type Handler interface { ServeHTTP(ResponseWriter, *Request) } // ListenAndServe startet den Server mit einem Handler. func ListenAndServe(addr string, handler Handler) error
  • 34. // HandlerFunc vereinfach den Handler zu nur einer Funktion. type HandlerFunc func(ResponseWriter, *Request) // ServeHTTP implementiert den Handler und führt nur die // Handler-Funktion aus. func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) }
  • 35. // ServeMux verteilt auf Handler nach Pfaden. type ServeMux struct { ... } func (mux *ServeMux) Handle(pattern string, handler Handler) { ... } // ServeHTTP implementiert Handler. func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { ... }
  • 36. Von einfachem Interface zu mehr • Multiplexer für HTTP Methoden • Multiplexer für Schachtelung bei RESTful APIs • Schachtelung für Trennung von Authentisierung/Autorisierung via JSON Web Tokens o.ä.
  • 37. Variablen explizit und implizit • Mit Deklaration via var oder mit Zuweisung durch := • Typisierung explizit oder implizit • var kennt beides, := ist immer implizit • Zuweisung mit =
  • 38. var s1 string // Deklaration s1 = "Hello" // Zuweisung var s2 string = "World" // Explizit mit Zuweisung var s3 = s1 + ", " + s2 // Implizit mit Zuweisung s4 := s3 + "!" // Deklaration implizit mit // Zuweisung
  • 40. Bedingungen • Mit if oder switch für logische Bedingungen • Mit select für Channel • switch und select kennen default an beliebiger Stelle • break nicht notwendig • switch verfügt über fallthrough für die Ausführung der Folgebedingung
  • 41. if x > y { x, y = y, x } if myFunctionReturnsTrue() { fmt.Println("Juchu!") } else { fmt.Println("Schade") }
  • 42. switch x { case 1, 2, 3: fmt.Println("1 bis 3") // Verpönte Weiterverarbeitung! fallthrough case 4, 5, 6: fmt.Println("4 bis 6") default: fmt.Println("Keine Ahnung") }
  • 43. // Abarbeitung von oben nach unten, aber default immer nur // wenn nichts passt. switch { case x < 0: fmt.Println("Kleiner als 0") default: fmt.Println("Ha! Genau 0") case x > 0: fmt.Println("Größer als 0") }
  • 44. select { case <-ctx.Done() return ctx.Err() case job := <-jobs: if err := job(); err != nil { log.Printf("job failed: %v", err) } case <-time.Tick(5 * time.Second): log.Printf("I'm waiting ...") }
  • 45. Schleifen • Schlüsselwort for • Verschiedene Formen der Bedingungen • Vorzeitige Fortsetzung über continue • Vorzeitiges Verlassen über break • Label für geschachtelte Schleifen • Arrays, Slices, Maps und Channel können mit range iteriert werden
  • 46. for { ... if shallLeave { break } } i := 0 for i < 2019 { ... i++ }
  • 47. for i := 0; i < 2019; i++ { if i % 2 == 0 { continue } ... } visitors := visitorsByConference("JAX 2019") for i, visitor := range visitors { fmt.Printf("Besucher %d ist %sn", i, visitor.Name) }
  • 49. Nebenläufigkeit • Leichtgewichtige Funktionen (Goroutinen) im Thread Pool • Schnelle Kontextwechsel • Kommunikation über typisierte Channel • Abfrage mehrerer Channel gleichzeitig über select • Start mit Schlüsselwort go • Gibt keine ID o.ä. zurück
  • 50. –Rob Pike „In programming, concurrency is the composition of independently executing processes, while parallelism is the simultaneous execution of (possibly related) computations. Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once.“
  • 52. • Einfacher Funktionsablauf im Hintergrund • „Mach mal.“ • Dito mit Rückgabe eines Ergebnisses über einen Channel • „Mach mal und bring mir dann das Ergebnis.“ • Kontinuierlicher Empfang zu verarbeitender Daten • „Kümmere dich um alle meine Aufträge.“ • Dito mit serialisiertem Zugriff auf einen privaten Zustand • „Sei mein schlauer Kollege.“
  • 56. Netze von Goroutinen Goroutine Goroutine Goroutine Goroutine Goroutine Goroutine Goroutine Goroutine Goroutine
  • 58. type Op func() // Calc ist ein Taschenrechner mit einem Wert als Zustand. type Calc struct { cancel context.CancelFunc ops chan Op value float64 }
  • 59. func New(ctx cancel.Context) *Calc { c := &Calc{ ops: make(chan Op, 1), value: 0.0, } ctx, c.cancel = context.WithCancel(ctx) go c.backend(ctx) return c }
  • 60. func (c *Calc) Stop() { c.cancel() }
  • 61. func (c *Calc) Add(v float64) (r float64) { wait := make(chan struct{}) c.ops <- func() { c.value += v r = c.value close(wait) log.Printf("calc added %f, new value is %f", v, r) } <-wait return }
  • 62. func (c *Calc) Div(v float64) (r float64, err error) { if v == 0 { return 0.0, errors.New("divide by zero") } wait := make(chan struct{}) c.ops <- func() { c.value /= v r = c.value close(wait) log.Printf("calc divided %f, new value is %f", v, r) } <-wait return }
  • 63. func (c *Calc) backend(ctx context.Context) { for { select { case <-ctx.Done(): return case op := <-c.ops: op() } } }
  • 65. Aufschieben • Funktionen können im Ablauf mit defer gestapelt werden • Werden rückwärts beim Verlassen der umgebenden Funktion ausgeführt • Praktisch für Aufräumarbeiten, zum Beispiel Schließen geöffneter Dateien
  • 66. file, err := ioutil.TempFile("/tmp", "jax2019") if err != nil { return fmt.Errorf("failed to open temp file: %v", err) } defer file.Close() writer := bufio.NewWriter(file) defer writer.Flush() writer.WriteString("JAX 2019n") writer.WriteString("Ein Gopher im Netzn")
  • 67. Fehlerbehandlung • Keine Exceptions • Fehlertyp error als letzter Rückgabewert • Interface mit Methode Error() string • panic() für echte Ausnahmesituationen • Kann mit recover() aufgefangen werden
  • 68. func CanBreakHard(x int) (err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("panic: %v", r) } }() ... if veryBadCondition { panic("have a very, yes, very, very bad condition") } return nil }
  • 70. Daten • Archivierung (tar, zip) • Komprimierung (bzip2, flate, gzip, lzw, zlib) • Encoding (ASN.1, CSV, JSON, XML) • Strings, Text, reguläre Ausdrücke • Text Templates • Time • Unicode
  • 71. Netz • Crypto (AES, Cipher, ECDSA, HMAC, RSA, SHA512, TLS) • Netzwerk • HTTP Client und Server • HTML Templates • JSON-RPC • SMTP
  • 72. Und vieles mehr ... • I/O • SQL Datenbanken • Synchronisation (Mutex, Once, WaitGroup), Context • Images • Reflection • Unit Tests
  • 74. Paradigmenmix ohne Overload • Sequentielle Abfolge von Anweisungen ➟ imperativ • Funktionstypen, Closures ➟ funktional • Methoden, Interfaces, Komposition ➟ objekt-orientiert • Goroutinen, Channels ➟ nebenläufig
  • 75. Fast wie Scripting • Einfache Syntax • Leichtgewichtiges Typenmodell • Wenige Schlüsselworte • Schnelle Kompilation erlaubt schnelle Tests • Aber: Manchmal mehrere Lösungswege möglich • Nutzung etablierter Konventionen hilft
  • 76. Einfache Nebenläufigkeit • Prinzipiell nur Funktionen • Flexible Kommunikation • Weitere Hilfen zur Synchronisation • Aber: Kein Schutz vor gleichzeitigem Zugriff auf Variablen • Aber: Kein Schutz vor Locks und Races • Tools helfen, ansonsten Verantwortung des Entwicklers