go_lernen
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| go_lernen [2026-01-26 11:20:42] – [Funktionen mit mehreren Parametern und Rückgaben] manfred | go_lernen [2026-01-28 10:47:47] (aktuell) – manfred | ||
|---|---|---|---|
| Zeile 16: | Zeile 16: | ||
| <code bash Hallo Welt> | <code bash Hallo Welt> | ||
| - | > vim hello_gopher.go | + | > vim hallo_gopher.go |
| package main | package main | ||
| import ( | import ( | ||
| Zeile 25: | Zeile 25: | ||
| } | } | ||
| - | > go build hello_gopher.go | + | > go build hallo_gopher.go |
| - | > ./hello_gopher | + | > ./hallo_gopher |
| Hallo Gopher! | Hallo Gopher! | ||
| </ | </ | ||
| Zeile 138: | Zeile 138: | ||
| Arrays haben eine feste Länge. | Arrays haben eine feste Länge. | ||
| - | Slices haben eine variable Länge, es entspricht einer " | + | Slices haben eine variable Länge, es entspricht einer " |
| <code go Array> | <code go Array> | ||
| Zeile 520: | Zeile 520: | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | |||
| + | === Methoden an Strukturen definieren === | ||
| + | |||
| + | <code go Struct_mit_Methode.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | // Struct | ||
| + | type Struktur01 struct { | ||
| + | Name string | ||
| + | alter int // mit kleinem Anfangsbuchstaben ist es ein privates Feld | ||
| + | } | ||
| + | |||
| + | // Methode | ||
| + | func (c Struktur01) methode01() { | ||
| + | fmt.Println(" | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | // normales Struct | ||
| + | c := Struktur01{Name: | ||
| + | |||
| + | // Aufruf Methode an Struct | ||
| + | c.methode01() | ||
| + | |||
| + | fmt.Println(c) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Mit Fehlern in Funktionen umgehen === | ||
| + | |||
| + | <code go Fehler_in_Funktionen.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | // Struktur | ||
| + | type Congressman struct { | ||
| + | Name | ||
| + | AccountBalance float64 | ||
| + | } | ||
| + | |||
| + | // Fehler als Rückgabewert | ||
| + | // Der Kontostand eines bestechlichen Abgeordneten wird von dieser Methode erhöht | ||
| + | // ist ein Abgeordneter nicht bestechlich, | ||
| + | func (c Congressman) bestechung(amount float64) error { | ||
| + | // ist der Name des Abgeordneten nicht Peter, so ist er nicht bestechlich | ||
| + | if c.Name != " | ||
| + | return fmt.Errorf(" | ||
| + | } | ||
| + | |||
| + | c.AccountBalance += amount | ||
| + | fmt.Println(c.Name, | ||
| + | |||
| + | return nil | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | //c := Congressman{Name: | ||
| + | c := Congressman{Name: | ||
| + | |||
| + | // Fehler behandeln | ||
| + | err := c.bestechung(5000.0) | ||
| + | if err != nil { | ||
| + | fmt.Println(" | ||
| + | } | ||
| + | |||
| + | fmt.Println(c) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | === generische Funktionen === | ||
| + | |||
| + | <code go generische_Funktionen.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | // generische Funktion | ||
| + | func humanAge[T int | float64](dogAge T) T { | ||
| + | return dogAge * 7 | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | // Funktion mit Typ Integer aufrufen | ||
| + | var i int = humanAge(3) | ||
| + | log.Println(i) | ||
| + | |||
| + | // Funktion mit Typ Fließkomma aufrufen | ||
| + | var j float64 = humanAge[float64](4.9) | ||
| + | log.Println(j) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | === anonyme Funktionen === | ||
| + | |||
| + | <code go anonyme_Funktionen.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func main() { | ||
| + | // anonyme Funktion definieren und ausführen | ||
| + | func () { | ||
| + | fmt.Println(" | ||
| + | }() | ||
| + | |||
| + | // anonyme HTTP-Handler-Funktion | ||
| + | http.HandleFunc("/", | ||
| + | w.Write([]byte(" | ||
| + | }) | ||
| + | http.ListenAndServe(": | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | === verzögerte Ausführung === | ||
| + | |||
| + | <code go verzögerte_Ausführung.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | // mit defer kann eine Ausführung verzögert werden | ||
| + | func halloDefer() { | ||
| + | defer fmt.Print(" | ||
| + | |||
| + | // defer wird auch bei einem Fehler ausgeführt | ||
| + | // hier greifen wir in einem Slice auf eine Stelle (Index) zu, | ||
| + | // die nicht existiert -> Fehler | ||
| + | //var s = []string{} | ||
| + | // | ||
| + | |||
| + | fmt.Print(" | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | // verzögerte Ausführung mit defer | ||
| + | halloDefer() | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | //Typische Anwendungsfälle für '' | ||
| + | |||
| + | |||
| + | ==== Schnittstellen mit Interfaces ==== | ||
| + | |||
| + | |||
| + | === Das Interface === | ||
| + | |||
| + | <code go hallo_interface.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | type Congressman struct { | ||
| + | Name string | ||
| + | } | ||
| + | |||
| + | func (c Congressman) greet() { | ||
| + | fmt.Println(" | ||
| + | } | ||
| + | |||
| + | type Enemy struct{} | ||
| + | |||
| + | func (e Enemy) greet() { | ||
| + | fmt.Println(" | ||
| + | } | ||
| + | |||
| + | // Interface definieren | ||
| + | type Greeter interface { | ||
| + | greet() | ||
| + | } | ||
| + | |||
| + | // Interface nutzen | ||
| + | func passBy(g1, g2 Greeter) { | ||
| + | g1.greet() | ||
| + | g2.greet() | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | // Interface | ||
| + | c := Congressman{Name: | ||
| + | e := Enemy{} | ||
| + | |||
| + | passBy(c, e) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | // | ||
| + | |||
| + | |||
| + | === Das Interface Stringer aus der Std-Lib === | ||
| + | |||
| + | <code go Stringer.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | type Struktur01 struct { | ||
| + | Name string | ||
| + | } | ||
| + | |||
| + | func (c Struktur01) Sring() string { | ||
| + | return " | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | c := Struktur01{Name: | ||
| + | fmt.Println(c) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code text> | ||
| + | $ go doc fmt.Stringer | ||
| + | package fmt // import " | ||
| + | |||
| + | type Stringer interface { | ||
| + | String() string | ||
| + | } | ||
| + | Stringer is implemented by any value that has a String method, which defines | ||
| + | the “native” format for that value. The String method is used to print | ||
| + | values passed as an operand to any format that accepts a string or to an | ||
| + | unformatted printer such as Print. | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Das leere Interface === | ||
| + | |||
| + | <code go leeres_interface.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func main() { | ||
| + | // Das leere Interface | ||
| + | var i interface{} = " | ||
| + | |||
| + | // Type Assertion heißt in anderen Sprachen Cast -> Typ-Umwandlung | ||
| + | |||
| + | // Type Assertion ohne Prüfung | ||
| + | var s string = i.(string) | ||
| + | fmt.Println(s) | ||
| + | |||
| + | // Type Assertion mit Prüfung | ||
| + | s2, ok := i.(string) | ||
| + | fmt.Println(s2, | ||
| + | |||
| + | // falsche Type Assertion ohne Prüfung erzeugt Panic | ||
| + | var f float64 = i.(float64) | ||
| + | fmt.Println(f) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Das io.Reader-Interface JSON verarbeiten === | ||
| + | |||
| + | <code go io-Reader-Interface.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func main() { | ||
| + | // normales Struct | ||
| + | const jsonBody = `{ " | ||
| + | var jsonMap map[string]string | ||
| + | |||
| + | r := strings.NewReader(jsonBody) | ||
| + | |||
| + | json.NewDecoder(r).Decode(& | ||
| + | |||
| + | fmt.Println(jsonMap) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Nebenläufig programmieren ==== | ||
| + | |||
| + | |||
| + | === Mit Go-Routinen und Channels nebenläufig programmieren === | ||
| + | |||
| + | <code go Go-Routine.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func Hallo(gruss string) { | ||
| + | fmt.Println(" | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | // Go-Routine | ||
| + | go Hallo(" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code go Go-Channel.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | // Deklarieren und Initialisieren | ||
| + | //a := make(chan string) | ||
| + | // | ||
| + | // Nachricht über Channel senden | ||
| + | //a <- " | ||
| + | // | ||
| + | // Nachricht von Channel empfangen, | ||
| + | // " | ||
| + | //value = <-a | ||
| + | // | ||
| + | //func Hallo(gruss string) { | ||
| + | // fmt.Println(" | ||
| + | //} | ||
| + | // | ||
| + | //func main() { | ||
| + | // // Go-Channel | ||
| + | // go Hallo(" | ||
| + | //} | ||
| + | |||
| + | func main() { | ||
| + | // 1. Channel erzeugen | ||
| + | money := make(chan int) | ||
| + | |||
| + | go func () { | ||
| + | // 3. Receive auf Channel money | ||
| + | amount := <-money | ||
| + | fmt.Println(" | ||
| + | }() | ||
| + | |||
| + | // 2. an Channel senden | ||
| + | money <- 200 | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code go 2-Sekunden_Go-Channel.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func cashflow(money chan int) { | ||
| + | amount := <-money | ||
| + | fmt.Println(" | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | money := make(chan int) | ||
| + | go cashflow(money) | ||
| + | |||
| + | money <- 1000 | ||
| + | |||
| + | time.Sleep(2 * time.Second) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code go mehrere_Go-Channels.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func cashflow(money chan int) { | ||
| + | // mit Select kann man gleichzeitig auf mehrere Channels lauschen | ||
| + | select { | ||
| + | case amount := <-money: | ||
| + | fmt.Println(" | ||
| + | case < | ||
| + | fmt.Println(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | money := make(chan int) | ||
| + | go cashflow(money) | ||
| + | |||
| + | // money <- 1000 | ||
| + | |||
| + | time.Sleep(2 * time.Second) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code go parallele_Worker.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func worker(id int) { | ||
| + | fmt.Printf(" | ||
| + | |||
| + | // durch schlafen wird aufwändige Verarbeitung simuliert | ||
| + | time.Sleep(time.Second) | ||
| + | |||
| + | fmt.Printf(" | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | // Parallele Worker mit der WaitGroup | ||
| + | var wg sync.WaitGroup | ||
| + | |||
| + | // hier werden 5 Worker in einer Schleife nacheinander gestartet | ||
| + | for i := 1; i <= 5; i++ { | ||
| + | wg.Add(1) | ||
| + | // weil sich alle Worker die Variable " | ||
| + | i := i | ||
| + | |||
| + | go func() { | ||
| + | defer wg.Done() | ||
| + | worker(i) | ||
| + | }() | ||
| + | } | ||
| + | |||
| + | // hier warten wir, bis alle Worker fertig sind | ||
| + | wg.Wait() | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code go parallele_Worker_-_Debatte.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func speaker(name string, debate chan int) { | ||
| + | for { | ||
| + | microphone := <-debate // auf Mic warten (Nachricht empfangen) | ||
| + | |||
| + | fmt.Printf(" | ||
| + | time.Sleep(400 * time.Millisecond) | ||
| + | |||
| + | microphone++ | ||
| + | debate <- microphone // Mic zurückgeben (Nachricht senden) | ||
| + | } | ||
| + | } | ||
| + | |||
| + | func randomAnswer() string { | ||
| + | answers := []string{" | ||
| + | return answers[rand.Intn(len(answers)-1)] | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | debate := make(chan int) | ||
| + | |||
| + | go speaker(" | ||
| + | go speaker(" | ||
| + | |||
| + | microphone := 1 | ||
| + | |||
| + | debate <- microphone | ||
| + | |||
| + | time.Sleep(2 * time.Second) | ||
| + | |||
| + | <-debate | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Praktische Aufgabe: Webserver für Go Proverbs ==== | ||
| + | |||
| + | |||
| + | === Basisprogramm: | ||
| + | |||
| + | <code bash> | ||
| + | > go mod init proserve | ||
| + | > go get github.com/ | ||
| + | go: downloading github.com/ | ||
| + | go: added github.com/ | ||
| + | </ | ||
| + | |||
| + | <code go Webserver_Proverbs.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func main() { | ||
| + | http.HandleFunc("/", | ||
| + | w.Write([]byte(" | ||
| + | }) | ||
| + | http.ListenAndServe(": | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | > go build Webserver_Proverbs.go | ||
| + | > ./ | ||
| + | [1] 274944 | ||
| + | |||
| + | > jobs | ||
| + | [1]+ Läuft | ||
| + | |||
| + | > curl localhost: | ||
| + | Hallo Proserve! | ||
| + | |||
| + | > killall Webserver_Proverbs | ||
| + | > jobs | ||
| + | [1]+ Beendet | ||
| + | </ | ||
| + | |||
| + | //Dieses Programm werden wir im folgenden erweitern...// | ||
| + | |||
| + | |||
| + | === Ersten Plain-Text-API-Endpoint umsetzen === | ||
| + | |||
| + | <code go Webserver_Proverbs.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | func main() { | ||
| + | http.HandleFunc("/", | ||
| + | w.Write([]byte(" | ||
| + | }) | ||
| + | |||
| + | // Plain Text Endpunkt | ||
| + | http.HandleFunc("/ | ||
| + | fmt.Fprintf(w, | ||
| + | }) | ||
| + | |||
| + | http.ListenAndServe(": | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | > curl localhost: | ||
| + | Hallo Proserve! | ||
| + | |||
| + | > curl localhost: | ||
| + | Make the zero value useful. | ||
| + | </ | ||
| + | |||
| + | |||
| + | === JSON-Endpoint === | ||
| + | |||
| + | <code go Webserver_Proverbs.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | type Proverb struct { | ||
| + | Saying string `json:" | ||
| + | Link string `json:" | ||
| + | } | ||
| + | |||
| + | func HandleProverbJson(w http.ResponseWriter, | ||
| + | randomProverb := proverbs.Random() | ||
| + | |||
| + | p := Proverb { | ||
| + | Saying: randomProverb.Saying, | ||
| + | Link: randomProverb.Link, | ||
| + | } | ||
| + | |||
| + | err := json.NewEncoder(w).Encode(p) | ||
| + | if err != nil { | ||
| + | http.Error(w, | ||
| + | } | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | http.HandleFunc("/", | ||
| + | w.Write([]byte(" | ||
| + | }) | ||
| + | |||
| + | // Plain Text Endpunkt | ||
| + | http.HandleFunc("/ | ||
| + | fmt.Fprintf(w, | ||
| + | }) | ||
| + | |||
| + | // JSON Endpunkt | ||
| + | http.HandleFunc("/ | ||
| + | |||
| + | http.ListenAndServe(": | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | > curl localhost: | ||
| + | {" | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Unit-Test: JSON-Endpoint === | ||
| + | |||
| + | <code go Webserver_Proverbs_test.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | type TestHandleProverbJson(t *testing.T) { | ||
| + | // 1. HTTP Recorder erstellen | ||
| + | recorder := httptest.NewRecorder() | ||
| + | |||
| + | // 2. HTTP Request | ||
| + | req, _ := http.NewRequest)" | ||
| + | |||
| + | // 3. HTTP-Händler aufrufen | ||
| + | HandleProverbJson(recorder, | ||
| + | |||
| + | // 4. Ergebnis prüfen | ||
| + | if recorder.Code != http.StatusOK { | ||
| + | t.Errorf(" | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Fehler behandeln === | ||
| + | |||
| + | <code go Webserver_Proverbs.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | type Proverb struct { | ||
| + | Saying string `json:" | ||
| + | Link string `json:" | ||
| + | } | ||
| + | |||
| + | func HandleProverbJson(w http.ResponseWriter, | ||
| + | randomProverb := proverbs.Random() | ||
| + | |||
| + | p := Proverb { | ||
| + | Saying: randomProverb.Saying, | ||
| + | Link: randomProverb.Link, | ||
| + | } | ||
| + | |||
| + | err := json.NewEncoder(w).Encode(p) | ||
| + | if err != nil { | ||
| + | http.Error(w, | ||
| + | } | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | http.HandleFunc("/", | ||
| + | w.Write([]byte(" | ||
| + | }) | ||
| + | |||
| + | // Plain Text Endpunkt | ||
| + | http.HandleFunc("/ | ||
| + | _, err := fmt.Fprintf(w, | ||
| + | if err != nil { | ||
| + | http.Error(w, | ||
| + | } | ||
| + | }) | ||
| + | |||
| + | // JSON Endpunkt | ||
| + | http.HandleFunc("/ | ||
| + | |||
| + | err := http.ListenAndServe(": | ||
| + | if err != nil { | ||
| + | log.Fatal(err) | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | > ./ | ||
| + | [1] 293523 | ||
| + | |||
| + | > ./ | ||
| + | 2026/01/27 16:32:12 listen tcp :8000: bind: address already in use | ||
| + | |||
| + | > killall Webserver_Proverbs | ||
| + | </ | ||
| + | |||
| + | |||
| + | === HTML-Seite für Proverbs === | ||
| + | |||
| + | <code go Webserver_Proverbs.go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | type Proverb struct { | ||
| + | Saying string `json:" | ||
| + | Link string `json:" | ||
| + | } | ||
| + | |||
| + | func HandleProverbJson(w http.ResponseWriter, | ||
| + | randomProverb := proverbs.Random() | ||
| + | |||
| + | p := Proverb { | ||
| + | Saying: randomProverb.Saying, | ||
| + | Link: randomProverb.Link, | ||
| + | } | ||
| + | |||
| + | err := json.NewEncoder(w).Encode(p) | ||
| + | if err != nil { | ||
| + | http.Error(w, | ||
| + | } | ||
| + | } | ||
| + | |||
| + | func HandleProverbPage(w http.ResponseWriter, | ||
| + | t, _ := template.New(" | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | err := t.Execute(w, | ||
| + | if err != nil { | ||
| + | http.Error(w, | ||
| + | } | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | http.HandleFunc("/", | ||
| + | |||
| + | // Plain Text Endpunkt | ||
| + | http.HandleFunc("/ | ||
| + | _, err := fmt.Fprintf(w, | ||
| + | if err != nil { | ||
| + | http.Error(w, | ||
| + | } | ||
| + | }) | ||
| + | |||
| + | // JSON Endpunkt | ||
| + | http.HandleFunc("/ | ||
| + | |||
| + | err := http.ListenAndServe(": | ||
| + | if err != nil { | ||
| + | log.Fatal(err) | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code html> | ||
| + | > ./ | ||
| + | [1] 296083 | ||
| + | |||
| + | > curl localhost: | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | > killall Webserver_Proverbs | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Das Makefile === | ||
| + | |||
| + | <file make Makefile> | ||
| + | BINARY = " | ||
| + | |||
| + | clean: | ||
| + | rm -f ${BINARY} | ||
| + | |||
| + | build: clean | ||
| + | go build -o ${BINARY} . | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Das Zen von Go ==== | ||
| + | |||
| + | - **einfach** | ||
| + | * Go erreicht viel mit wenig. Ein Programm sollte eine Sache tun, und die gut. | ||
| + | - **bescheiden** | ||
| + | * Unser Kode soll klar, idiomatisch und verständlich sein und seinen Zweck gut erfüllen. Clever ist da hinderlich. | ||
| + | - **Handeln durch Nichthandeln** | ||
| + | * Probleme eliminieren und Umwege vermeiden. Bewusstes Nichthandeln als Alternative zur Problemlösung und Umsetzung nutzen. | ||
| + | |||
| + | |||
| + | ==== Ideen für erste Projekte ==== | ||
| + | |||
| + | * Go eignet sich besonders für... | ||
| + | * Microservices | ||
| + | * Serverless Funktions | ||
| + | * Kommandozeilen-Tools | ||
| + | * DevOps und Cloud-Automatisierung | ||
| + | |||
| + | |||
| + | ===== ...weiter machen... ===== | ||
| + | |||
| + | [[https:// | ||
/home/http/wiki/data/attic/go_lernen.1769426442.txt · Zuletzt geändert: von manfred
