SlideShare ist ein Scribd-Unternehmen logo
1 von 77
Downloaden Sie, um offline zu lesen
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

Was ist angesagt?

Übersicht Skriptsprachen
Übersicht SkriptsprachenÜbersicht Skriptsprachen
Übersicht SkriptsprachenA. LE
 
Architektur einer Eclipse DLTK IDE für Clojure
Architektur einer Eclipse DLTK IDE für ClojureArchitektur einer Eclipse DLTK IDE für Clojure
Architektur einer Eclipse DLTK IDE für ClojureMatthias Köster
 
Go - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeGo - Googles Sprache für skalierbare Systeme
Go - Googles Sprache für skalierbare SystemeFrank Müller
 
Metaprogrammierung mit Ruby
Metaprogrammierung mit RubyMetaprogrammierung mit Ruby
Metaprogrammierung mit RubyDario Rexin
 
Infrastructure as Code - BaselOne 17
Infrastructure as Code - BaselOne 17Infrastructure as Code - BaselOne 17
Infrastructure as Code - BaselOne 17remigius-stalder
 
Cloud Provisioning mit Juju
Cloud Provisioning mit JujuCloud Provisioning mit Juju
Cloud Provisioning mit JujuFrank Müller
 
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices".NET und jetzt!" C# in 21 Tagen oder doch besser Best Practices
".NET und jetzt!" C# in 21 Tagen oder doch besser Best PracticesGFU Cyrus AG
 
Referat T13 Javadoc
Referat T13 JavadocReferat T13 Javadoc
Referat T13 Javadocminiroquer
 
Einführung in die funktionale Programmierung mit Clojure
Einführung in die funktionale Programmierung mit ClojureEinführung in die funktionale Programmierung mit Clojure
Einführung in die funktionale Programmierung mit ClojureSascha Koch
 
Ruby is Magic - Episode #7: Closures
Ruby is Magic - Episode #7: ClosuresRuby is Magic - Episode #7: Closures
Ruby is Magic - Episode #7: ClosuresDirk Breuer
 
Scalaz introduction for Java programmers
Scalaz introduction for Java programmersScalaz introduction for Java programmers
Scalaz introduction for Java programmersBernhard Huemer
 
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...
OSMC 2008 | Programmierung von Nagios-Plugins für NetApp Speichergeräte by In...NETWAYS
 
Verteilte Anwendungen bei Azure mit Docker und Kubernetes
Verteilte Anwendungen bei Azure mit Docker und KubernetesVerteilte Anwendungen bei Azure mit Docker und Kubernetes
Verteilte Anwendungen bei Azure mit Docker und KubernetesGregor Biswanger
 
Interprozesskommunikation mit PHP
Interprozesskommunikation mit PHPInterprozesskommunikation mit PHP
Interprozesskommunikation mit PHPStephan Schmidt
 
Check cisco voice
Check cisco voiceCheck cisco voice
Check cisco voicebboguhn
 
TMQL tutorial - part 4
TMQL tutorial - part 4TMQL tutorial - part 4
TMQL tutorial - part 4Lutz Maicher
 

Was ist angesagt? (20)

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

Ähnlich wie Ein Gopher im Netz

Java und Go im Vergleich
Java und Go im VergleichJava und Go im Vergleich
Java und Go im VergleichQAware GmbH
 
Ruby und Rails für .NET Entwickler
Ruby und Rails für .NET EntwicklerRuby und Rails für .NET Entwickler
Ruby und Rails für .NET EntwicklerNETUserGroupBern
 
Vagrant - Einführung & Verwendung
Vagrant - Einführung & VerwendungVagrant - Einführung & Verwendung
Vagrant - Einführung & VerwendungTilo Baller
 
Skalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoSkalierbare Anwendungen mit Google Go
Skalierbare Anwendungen mit Google GoFrank Müller
 
Javascript done right
Javascript done rightJavascript done right
Javascript done rightDirk Ginader
 
Schweine latein-vortrag
Schweine latein-vortragSchweine latein-vortrag
Schweine latein-vortragRamon Wartala
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsJosef Adersberger
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsQAware GmbH
 
JavaScript für Java-Entwickler W-JAX 2013
JavaScript für Java-Entwickler W-JAX 2013JavaScript für Java-Entwickler W-JAX 2013
JavaScript für Java-Entwickler W-JAX 2013Oliver Zeigermann
 
FMK2022 Neue Programmiertechniken von Adam Augusting
FMK2022 Neue Programmiertechniken von Adam AugustingFMK2022 Neue Programmiertechniken von Adam Augusting
FMK2022 Neue Programmiertechniken von Adam AugustingVerein FM Konferenz
 
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...OPEN KNOWLEDGE GmbH
 
FMK 2013 Konstrukte diverser Programmiersprachen in FileMaker nachgebaut, Tho...
FMK 2013 Konstrukte diverser Programmiersprachen in FileMaker nachgebaut, Tho...FMK 2013 Konstrukte diverser Programmiersprachen in FileMaker nachgebaut, Tho...
FMK 2013 Konstrukte diverser Programmiersprachen in FileMaker nachgebaut, Tho...Verein FM Konferenz
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershellCreasoft AG
 
Back to the future - Plone 5.2 und Python 3 Migration am Beispiel Onkopedia
Back to the future - Plone 5.2 und Python 3 Migration am Beispiel OnkopediaBack to the future - Plone 5.2 und Python 3 Migration am Beispiel Onkopedia
Back to the future - Plone 5.2 und Python 3 Migration am Beispiel OnkopediaAndreas Jung
 
Vagrant, Puppet, Docker für Entwickler und Architekten
Vagrant, Puppet, Docker für Entwickler und ArchitektenVagrant, Puppet, Docker für Entwickler und Architekten
Vagrant, Puppet, Docker für Entwickler und ArchitektenOPITZ CONSULTING Deutschland
 
Ist GraphQL das bessere REST
Ist GraphQL das bessere RESTIst GraphQL das bessere REST
Ist GraphQL das bessere RESTMartin Abraham
 

Ähnlich wie Ein Gopher im Netz (20)

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

Mehr von Frank Müller

JAX 2023 - Cloud Provider APIs
JAX 2023 - Cloud Provider APIsJAX 2023 - Cloud Provider APIs
JAX 2023 - Cloud Provider APIsFrank Müller
 
JAX 2023 - Generics in Go
JAX 2023 - Generics in GoJAX 2023 - Generics in Go
JAX 2023 - Generics in GoFrank Müller
 
Let The Computer Do It
Let The Computer Do ItLet The Computer Do It
Let The Computer Do ItFrank Müller
 
2021 OOP - Kubernetes Operatoren
2021   OOP - Kubernetes Operatoren2021   OOP - Kubernetes Operatoren
2021 OOP - Kubernetes OperatorenFrank Müller
 
Blockchains - Mehr als nur digitale Währungen
Blockchains - Mehr als nur digitale WährungenBlockchains - Mehr als nur digitale Währungen
Blockchains - Mehr als nur digitale WährungenFrank Müller
 
Juju - Scalable Software with Google Go
Juju - Scalable Software with Google GoJuju - Scalable Software with Google Go
Juju - Scalable Software with Google GoFrank Müller
 
RESTful Web Applications with Google Go
RESTful Web Applications with Google GoRESTful Web Applications with Google Go
RESTful Web Applications with Google GoFrank Müller
 
Clouds, leicht beherrschbar
Clouds, leicht beherrschbarClouds, leicht beherrschbar
Clouds, leicht beherrschbarFrank Müller
 
WTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
WTC 2013 - Juju - Mit etwas Magie zur perfekten CloudWTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
WTC 2013 - Juju - Mit etwas Magie zur perfekten CloudFrank Müller
 
Juju - Google Go in a scalable Environment
Juju - Google Go in a scalable EnvironmentJuju - Google Go in a scalable Environment
Juju - Google Go in a scalable EnvironmentFrank Müller
 
OOP 2013 - Weltweite Entwicklung von Open Source Software
OOP 2013 - Weltweite Entwicklung von Open Source SoftwareOOP 2013 - Weltweite Entwicklung von Open Source Software
OOP 2013 - Weltweite Entwicklung von Open Source SoftwareFrank Müller
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of GoFrank Müller
 
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
Pecha Kucha: Nebenläufigkeit als natürliches ParadigmaPecha Kucha: Nebenläufigkeit als natürliches Paradigma
Pecha Kucha: Nebenläufigkeit als natürliches ParadigmaFrank Müller
 
On Event-Driven Architecture
On Event-Driven ArchitectureOn Event-Driven Architecture
On Event-Driven ArchitectureFrank Müller
 
Google Go - Good artists borrow, great artists steal.
Google Go - Good artists borrow, great artists steal.Google Go - Good artists borrow, great artists steal.
Google Go - Good artists borrow, great artists steal.Frank Müller
 
Agility And The Way To SOA
Agility And The Way To SOAAgility And The Way To SOA
Agility And The Way To SOAFrank Müller
 

Mehr von Frank Müller (19)

JAX 2023 - Cloud Provider APIs
JAX 2023 - Cloud Provider APIsJAX 2023 - Cloud Provider APIs
JAX 2023 - Cloud Provider APIs
 
JAX 2023 - Generics in Go
JAX 2023 - Generics in GoJAX 2023 - Generics in Go
JAX 2023 - Generics in Go
 
Let The Computer Do It
Let The Computer Do ItLet The Computer Do It
Let The Computer Do It
 
Concurrency with Go
Concurrency with GoConcurrency with Go
Concurrency with Go
 
2021 OOP - Kubernetes Operatoren
2021   OOP - Kubernetes Operatoren2021   OOP - Kubernetes Operatoren
2021 OOP - Kubernetes Operatoren
 
Fun with functions
Fun with functionsFun with functions
Fun with functions
 
Blockchains - Mehr als nur digitale Währungen
Blockchains - Mehr als nur digitale WährungenBlockchains - Mehr als nur digitale Währungen
Blockchains - Mehr als nur digitale Währungen
 
Juju - Scalable Software with Google Go
Juju - Scalable Software with Google GoJuju - Scalable Software with Google Go
Juju - Scalable Software with Google Go
 
RESTful Web Applications with Google Go
RESTful Web Applications with Google GoRESTful Web Applications with Google Go
RESTful Web Applications with Google Go
 
Clouds, leicht beherrschbar
Clouds, leicht beherrschbarClouds, leicht beherrschbar
Clouds, leicht beherrschbar
 
WTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
WTC 2013 - Juju - Mit etwas Magie zur perfekten CloudWTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
WTC 2013 - Juju - Mit etwas Magie zur perfekten Cloud
 
Juju - Google Go in a scalable Environment
Juju - Google Go in a scalable EnvironmentJuju - Google Go in a scalable Environment
Juju - Google Go in a scalable Environment
 
OOP 2013 - Weltweite Entwicklung von Open Source Software
OOP 2013 - Weltweite Entwicklung von Open Source SoftwareOOP 2013 - Weltweite Entwicklung von Open Source Software
OOP 2013 - Weltweite Entwicklung von Open Source Software
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
Pecha Kucha: Nebenläufigkeit als natürliches ParadigmaPecha Kucha: Nebenläufigkeit als natürliches Paradigma
Pecha Kucha: Nebenläufigkeit als natürliches Paradigma
 
Go to the Cloud
Go to the CloudGo to the Cloud
Go to the Cloud
 
On Event-Driven Architecture
On Event-Driven ArchitectureOn Event-Driven Architecture
On Event-Driven Architecture
 
Google Go - Good artists borrow, great artists steal.
Google Go - Good artists borrow, great artists steal.Google Go - Good artists borrow, great artists steal.
Google Go - Good artists borrow, great artists steal.
 
Agility And The Way To SOA
Agility And The Way To SOAAgility And The Way To SOA
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