Benutzer-Werkzeuge

Webseiten-Werkzeuge


go_lernen

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
go_lernen [2026-01-23 16:28:46] – [for-Schleife] manfredgo_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!
 </code> </code>
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 "Liste" in C++ oder Java.+Slices haben eine variable Länge, es entspricht einer "Liste" in ''%%C++%%'' oder ''Java''.
  
 <code go Array> <code go Array>
Zeile 466: Zeile 466:
 } }
 </code> </code>
 +
 +
 +==== Funktionen und Methoden ====
 +
 +
 +=== einfache Funktionen ===
 +
 +<code go einfache_Funktionen.go>
 +package main
 + 
 +import (
 +        "fmt"
 +)
 +
 +func humanAge1(dogAge int) int {
 +        return dogAge * 7 
 +}
 +
 +func humanAge2(dogAge int) (humanAge int) {
 +        humanAge = dogAge * 7 
 +        return
 +}
 +
 +func main() {
 +        // Übung: Alter vom Hund in Menschenjahren und Hundejahren
 +        hassoAge := 3
 +        fmt.Println("1. Menschenalter von Hasso", humanAge1(hassoAge))
 +        fmt.Println("2. Menschenalter von Hasso", humanAge2(hassoAge))
 +}
 +</code>
 +
 +
 +=== Funktionen mit mehreren Parametern und Rückgaben ===
 +
 +<code go Funktionen_mit_mehreren_Parametern.go>
 +package main
 +
 +import (
 +        "fmt"
 +)
 +
 +func humanAge(dogAge int) int {
 +        return dogAge * 7
 +}
 +
 +func humanAges(dog1, dog2 int) (int, int) {
 +        return humanAge(dog1), humanAge(dog2)
 +}
 +
 +func main() {
 +        human1, human2 := humanAges(3, 5)
 +        fmt.Println("Human Ages:", human1, ",", human2)
 +}
 +</code>
 +
 +
 +=== Methoden an Strukturen definieren ===
 +
 +<code go Struct_mit_Methode.go>
 +package main
 + 
 +import (
 +        "fmt"
 +)
 +
 +// Struct
 +type Struktur01 struct {
 + Name string    // mit großem Anfangsbuchstaben ist es ein öffentliches Feld
 + alter int      // mit kleinem Anfangsbuchstaben ist es ein privates Feld
 +}
 + 
 +// Methode
 +func (c Struktur01) methode01() {
 + fmt.Println("Ausgabe der Methode:", c.Name)
 +}
 + 
 +func main() {
 + // normales Struct
 + c := Struktur01{Name: "Alfred Nobel", alter: 63}
 +
 + // Aufruf Methode an Struct
 + c.methode01()
 +
 + fmt.Println(c)
 +}
 +</code>
 +
 +
 +=== Mit Fehlern in Funktionen umgehen ===
 +
 +<code go Fehler_in_Funktionen.go>
 +package main
 + 
 +import (
 +        "fmt"
 +)
 +
 +// Struktur
 +type Congressman struct {
 + Name           string
 + AccountBalance float64
 +}
 + 
 +// Fehler als Rückgabewert
 +// Der Kontostand eines bestechlichen Abgeordneten wird von dieser Methode erhöht
 +// ist ein Abgeordneter nicht bestechlich, wird ein Fehler ausgegeben
 +func (c Congressman) bestechung(amount float64) error {
 + // ist der Name des Abgeordneten nicht Peter, so ist er nicht bestechlich
 + if c.Name != "Peter" {
 + return fmt.Errorf("%v ist nicht koruppt", c.Name)
 + }
 +
 + c.AccountBalance += amount
 + fmt.Println(c.Name, "hat", c.AccountBalance)
 +
 + return nil
 +}
 + 
 +func main() {
 + //c := Congressman{Name: "Jacjie", AccountBalance: 8000.0}
 + c := Congressman{Name: "Peter", AccountBalance: 8000.0}
 +
 + // Fehler behandeln
 + err := c.bestechung(5000.0)
 + if err != nil {
 + fmt.Println("Ein Abgeordneter konnte nicht bestochen werden:", err)
 + }
 +
 + fmt.Println(c)
 +}
 +</code>
 +
 +
 +=== generische Funktionen ===
 +
 +<code go generische_Funktionen.go>
 +package main
 + 
 +import (
 +        "log"
 +)
 +
 +// 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)
 +}
 +</code>
 +
 +
 +=== anonyme Funktionen ===
 +
 +<code go anonyme_Funktionen.go>
 +package main
 + 
 +import (
 + "fmt"
 + "net/http"
 +)
 +
 +func main() {
 + // anonyme Funktion definieren und ausführen
 + func () {
 + fmt.Println("Hallo Welt")
 + }()
 +
 + // anonyme HTTP-Handler-Funktion
 + http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
 + w.Write([]byte("Hallo Welt"))
 + })
 + http.ListenAndServe(":8080")
 +}
 +</code>
 +
 +
 +=== verzögerte Ausführung ===
 +
 +<code go verzögerte_Ausführung.go>
 +package main
 +
 +import (
 +        "fmt"
 +)
 +
 +// mit defer kann eine Ausführung verzögert werden
 +func halloDefer() {
 +        defer fmt.Print("Welt\n")
 +
 +        // 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.Println("Huch ", s[42])
 +
 +        fmt.Print("Hallo ")
 +}
 +
 +func main() {
 +        // verzögerte Ausführung mit defer
 +        halloDefer()
 +}
 +</code>
 +
 +//Typische Anwendungsfälle für ''defer'' sind "Dateien schließen", "Dateien löschen" oder "Speicher freigeben".//
 +
 +
 +==== Schnittstellen mit Interfaces ====
 +
 +
 +=== Das Interface ===
 +
 +<code go hallo_interface.go>
 +package main
 +
 +import (
 +        "fmt"
 +)
 +
 +type Congressman struct {
 +        Name string
 +}
 +
 +func (c Congressman) greet() {
 +        fmt.Println("Hallo", c.Name)
 +}
 +
 +type Enemy struct{}
 +
 +func (e Enemy) greet() {
 +        fmt.Println("Go to hell!")
 +}
 +
 +// Interface definieren
 +type Greeter interface {
 +        greet()
 +}
 +
 +// Interface nutzen
 +func passBy(g1, g2 Greeter) {
 +        g1.greet()
 +        g2.greet()
 +}
 +
 +func main() {
 +        // Interface
 +        c := Congressman{Name: "Frank"}
 +        e := Enemy{}
 +
 +        passBy(c, e)
 +}
 +</code>
 +
 +//Interfaces werden in Go nicht explizit, sondern implizit integriert.//
 +
 +
 +=== Das Interface Stringer aus der Std-Lib ===
 +
 +<code go Stringer.go>
 +package main
 + 
 +import (
 +        "fmt"
 +)
 +
 +type Struktur01 struct {
 + Name string
 +}
 + 
 +func (c Struktur01) Sring() string {
 + return "Hallo! " + c.Name
 +}
 + 
 +func main() {
 + c := Struktur01{Name: "Alfred Nobel"}
 + fmt.Println(c)
 +}
 +</code>
 +
 +<code text>
 +$ go doc fmt.Stringer
 +package fmt // import "fmt"
 +
 +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.
 +</code>
 +
 +
 +=== Das leere Interface ===
 +
 +<code go leeres_interface.go>
 +package main
 + 
 +import (
 +        "fmt"
 +)
 +
 +func main() {
 +        // Das leere Interface
 +        var i interface{} = "Hallo"
 +
 +        // 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, "ist es ein String?", ok)
 +
 +        // falsche Type Assertion ohne Prüfung erzeugt Panic
 +        var f float64 = i.(float64)
 +        fmt.Println(f)
 +}
 +</code>
 +
 +
 +=== Das io.Reader-Interface JSON verarbeiten ===
 +
 +<code go io-Reader-Interface.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "strings"
 +        "encoding/json"
 +)
 +
 +func main() {
 +        // normales Struct
 +        const jsonBody = `{ "Nachricht": "Hallo Leser!" }`
 +        var jsonMap map[string]string
 +
 +        r := strings.NewReader(jsonBody)
 +
 +        json.NewDecoder(r).Decode(&jsonMap)
 +
 +        fmt.Println(jsonMap)
 +}
 +</code>
 +
 +
 +==== Nebenläufig programmieren ====
 +
 +
 +=== Mit Go-Routinen und Channels nebenläufig programmieren ===
 +
 +<code go Go-Routine.go>
 +package main
 +
 +import (
 +        "fmt"
 +)
 +
 +func Hallo(gruss string) {
 +        fmt.Println("Hallo", gruss)
 +}
 +
 +func main() {
 +        // Go-Routine
 +        go Hallo("Welt")
 +}
 +</code>
 +
 +<code go Go-Channel.go>
 +package main
 +
 +import (
 +        "fmt"
 +)
 +
 +// Deklarieren und Initialisieren
 +//a := make(chan string)
 +//
 +// Nachricht über Channel senden
 +//a <- "Hallo"
 +//
 +// Nachricht von Channel empfangen,
 +// "Pfeil" gibt Richtung des Datenflusses an
 +//value = <-a
 +//
 +//func Hallo(gruss string) {
 +//      fmt.Println("Hallo", gruss)
 +//}
 +//
 +//func main() {
 +//      // Go-Channel
 +//      go Hallo("Welt")
 +//}
 +
 +func main() {
 +        // 1. Channel erzeugen
 +        money := make(chan int)
 +
 +        go func () {
 +                // 3. Receive auf Channel money
 +                amount := <-money
 +                fmt.Println("empfangen:", amount, "€")
 +        }()
 +
 +        // 2. an Channel senden
 +        money <- 200
 +}
 +</code>
 +
 +<code go 2-Sekunden_Go-Channel.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "time"
 +)
 +
 +func  cashflow(money chan int) {
 +        amount := <-money
 +        fmt.Println("empfangen:", amount, "€")
 +}
 +
 +func main() { 
 +        money := make(chan int)
 +        go cashflow(money)
 +
 +        money <- 1000
 +
 +        time.Sleep(2 * time.Second)
 +}
 +</code>
 +
 +<code go mehrere_Go-Channels.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "time"
 +)
 +
 +func  cashflow(money chan int) {
 +        // mit Select kann man gleichzeitig auf mehrere Channels lauschen
 +        select {
 +        case amount := <-money:
 +                fmt.Println("empfangen:", amount, "€")
 +        case <-time.After(1 * time.Second):
 +                fmt.Println("...kein Geld bekommen!!!")
 +        }
 +}
 +
 +func main() {
 +        money := make(chan int)
 +        go cashflow(money)
 +
 +//      money <- 1000
 +
 +        time.Sleep(2 * time.Second)
 +}
 +</code>
 +
 +<code go parallele_Worker.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "time"
 +        "sync"
 +)
 +
 +func worker(id int) {
 +        fmt.Printf("Worker %d startet\n", id)
 +
 +        // durch schlafen wird aufwändige Verarbeitung simuliert
 +        time.Sleep(time.Second)
 +
 +        fmt.Printf("Worker %d ist fertig\n", id)
 +}
 +
 +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" teilen, brauchen wir hier noch eine eigene Kopie von "i"
 +                i := i
 +
 +                go func() {
 +                        defer wg.Done()
 +                        worker(i)
 +                }()
 +        }
 +
 +        // hier warten wir, bis alle Worker fertig sind
 +        wg.Wait()
 +}
 +</code>
 +
 +<code go parallele_Worker_-_Debatte.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "time"
 +        "math/rand"
 +)
 +
 +func speaker(name string, debate chan int) {
 +        for {
 +                microphone := <-debate // auf Mic warten (Nachricht empfangen)
 +
 +                fmt.Printf("Turn %v: %v says '%v'\n", microphone, name, randomAnswer())
 +                time.Sleep(400 * time.Millisecond)
 +
 +                microphone++
 +                debate <- microphone // Mic zurückgeben (Nachricht senden)
 +        }
 +}
 +
 +func randomAnswer() string {
 +        answers := []string{"Ich habe Recht", "Nimm dieses Argument.", "Aber ich habe diese Erfahrung gemacht.", "Du ***"}
 +        return answers[rand.Intn(len(answers)-1)]
 +}
 +
 +func main() {
 +        debate := make(chan int)
 +
 +        go speaker("Jackie", debate)
 +        go speaker("Frank", debate)
 +
 +        microphone := 1
 +
 +        debate <- microphone
 +
 +        time.Sleep(2 * time.Second)
 +
 +        <-debate
 +}
 +</code>
 +
 +
 +==== Praktische Aufgabe: Webserver für Go Proverbs ====
 +
 +
 +=== Basisprogramm: Webserver Proverbs ===
 +
 +<code bash>
 +> go mod init proserve
 +> go get github.com/jboursiquot/go-proverbs
 +go: downloading github.com/jboursiquot/go-proverbs v0.0.2
 +go: added github.com/jboursiquot/go-proverbs v0.0.2
 +</code>
 +
 +<code go Webserver_Proverbs.go>
 +package main
 +
 +import (
 +        "net/http"
 +)
 +
 +func main() {
 +        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 +                w.Write([]byte("Hallo Proserve!\n"))
 +        })
 +        http.ListenAndServe(":8000", nil)
 +}
 +</code>
 +
 +<code bash>
 +> go build Webserver_Proverbs.go
 +> ./Webserver_Proverbs &
 +[1] 274944
 +
 +> jobs
 +[1]+  Läuft                  ./Webserver_Proverbs &
 +
 +> curl localhost:8000
 +Hallo Proserve!
 +
 +> killall Webserver_Proverbs
 +> jobs
 +[1]+  Beendet                 ./Webserver_Proverbs
 +</code>
 +
 +//Dieses Programm werden wir im folgenden erweitern...//
 +
 +
 +=== Ersten Plain-Text-API-Endpoint umsetzen ===
 +
 +<code go Webserver_Proverbs.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "net/http"
 +        "github.com/jboursiquot/go-proverbs"
 +)
 +
 +func main() {
 +        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 +                w.Write([]byte("Hallo Proserve!"))
 +        })
 +
 +        // Plain Text Endpunkt
 +        http.HandleFunc("/text", func(w http.ResponseWriter, r *http.Request) {
 +                fmt.Fprintf(w, proverbs.Random().Saying)
 +        })
 +
 +        http.ListenAndServe(":8000", nil)
 +}
 +</code>
 +
 +<code bash>
 +> curl localhost:8000/ ; echo
 +Hallo Proserve!
 +
 +> curl localhost:8000/text ; echo
 +Make the zero value useful.
 +</code>
 +
 +
 +=== JSON-Endpoint ===
 +
 +<code go Webserver_Proverbs.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "net/http"
 +        "github.com/jboursiquot/go-proverbs"
 +        "encoding/json"
 +)
 +
 +type Proverb struct {
 +        Saying string `json:"saying"`
 +        Link string `json:"link"`
 +}
 +
 +func HandleProverbJson(w http.ResponseWriter, r *http.Request) {
 +        randomProverb := proverbs.Random()
 +
 +        p := Proverb {
 +                Saying: randomProverb.Saying,
 +                Link: randomProverb.Link,
 +        }
 +
 +        err := json.NewEncoder(w).Encode(p)
 +        if err != nil {
 +                http.Error(w, "uups, da ist etwas schief gegangen!", http.StatusInternalServerError)
 +        }
 +}
 +
 +func main() {
 +        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 +                w.Write([]byte("Hallo Proserve!"))
 +        })
 +
 +        // Plain Text Endpunkt
 +        http.HandleFunc("/text", func(w http.ResponseWriter, r *http.Request) {
 +                fmt.Fprintf(w, proverbs.Random().Saying)
 +        })
 +
 +        // JSON Endpunkt
 +        http.HandleFunc("/api", HandleProverbJson)
 +
 +        http.ListenAndServe(":8000", nil)
 +}
 +</code>
 +
 +<code bash>
 +> curl localhost:8000/api ; echo
 +{"saying":"interface{} says nothing.","link":"https://www.youtube.com/watch?v=PAAkCSZUG1c\u0026t=7m36s"}
 +</code>
 +
 +
 +=== Unit-Test: JSON-Endpoint ===
 +
 +<code go Webserver_Proverbs_test.go>
 +package main
 +
 +import (
 +        "net/http"
 +        "net/http/httptest"
 +        "testing"
 +)
 +
 +type TestHandleProverbJson(t *testing.T) {
 +        // 1. HTTP Recorder erstellen
 +        recorder := httptest.NewRecorder()
 +
 +        // 2. HTTP Request
 +        req, _ := http.NewRequest)"GET", "/api", nil)
 +
 +        // 3. HTTP-Händler aufrufen
 +        HandleProverbJson(recorder, req)
 +
 +        // 4. Ergebnis prüfen
 +        if recorder.Code != http.StatusOK {
 +                t.Errorf("fehlerhafter Status %v, erwarteter Status %v", recorder.Code, http.StatusOK)
 +        }
 +}
 +</code>
 +
 +
 +=== Fehler behandeln ===
 +
 +<code go Webserver_Proverbs.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "net/http"
 +        "github.com/jboursiquot/go-proverbs"
 +        "encoding/json"
 +        "log"
 +)
 +
 +type Proverb struct {
 +        Saying string `json:"saying"`
 +        Link string `json:"link"`
 +}
 +
 +func HandleProverbJson(w http.ResponseWriter, r *http.Request) {
 +        randomProverb := proverbs.Random()
 +
 +        p := Proverb {
 +                Saying: randomProverb.Saying,
 +                Link: randomProverb.Link,
 +        }
 +
 +        err := json.NewEncoder(w).Encode(p)
 +        if err != nil {
 +                http.Error(w, "uups, da ist etwas schief gegangen!", http.StatusInternalServerError)
 +        }
 +}
 +
 +func main() {
 +        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 +                w.Write([]byte("Hallo Proserve!"))
 +        })
 +
 +        // Plain Text Endpunkt
 +        http.HandleFunc("/text", func(w http.ResponseWriter, r *http.Request) {
 +                _, err := fmt.Fprintf(w, proverbs.Random().Saying)
 +                if err != nil {
 +                        http.Error(w, "uups, da ist etwas schief gegangen!", http.StatusInternalServerError)
 +                }
 +        })
 +
 +        // JSON Endpunkt
 +        http.HandleFunc("/api", HandleProverbJson)
 +
 +        err := http.ListenAndServe(":8000", nil)
 +        if err != nil {
 +                log.Fatal(err)
 +        }
 +}
 +</code>
 +
 +<code bash>
 +> ./Webserver_Proverbs &
 +[1] 293523
 +
 +> ./Webserver_Proverbs
 +2026/01/27 16:32:12 listen tcp :8000: bind: address already in use
 +
 +> killall Webserver_Proverbs
 +</code>
 +
 +
 +=== HTML-Seite für Proverbs ===
 +
 +<code go Webserver_Proverbs.go>
 +package main
 +
 +import (
 +        "fmt"
 +        "net/http"
 +        "github.com/jboursiquot/go-proverbs"
 +        "encoding/json"
 +        "log"
 +        "html/template"
 +)
 +
 +type Proverb struct {
 +        Saying string `json:"saying"`
 +        Link string `json:"link"`
 +}
 +
 +func HandleProverbJson(w http.ResponseWriter, r *http.Request) {
 +        randomProverb := proverbs.Random()
 +
 +        p := Proverb {
 +                Saying: randomProverb.Saying,
 +                Link: randomProverb.Link,
 +        }
 +
 +        err := json.NewEncoder(w).Encode(p)
 +        if err != nil {
 +                http.Error(w, "uups, da ist etwas schief gegangen!", http.StatusInternalServerError)
 +        }
 +}
 +
 +func HandleProverbPage(w http.ResponseWriter, r *http.Request) {
 +        t, _ := template.New("page").Parse(`<html>
 +        <head></head>
 +        <body>
 +                <h1>Your Proverb: <a href="{{ .Link }}">{{ .Saying }}</a></h1>
 +        </body>
 +</html>`)
 +        err := t.Execute(w, proverbs.Random())
 +        if err != nil {
 +                http.Error(w, "uups, da ist etwas schief gegangen!", http.StatusInternalServerError)
 +        }
 +}
 +
 +func main() {
 +        http.HandleFunc("/", HandleProverbPage)
 +
 +        // Plain Text Endpunkt
 +        http.HandleFunc("/text", func(w http.ResponseWriter, r *http.Request) {
 +                _, err := fmt.Fprintf(w, proverbs.Random().Saying)
 +                if err != nil {
 +                        http.Error(w, "uups, da ist etwas schief gegangen!", http.StatusInternalServerError)
 +                }
 +        })
 +
 +        // JSON Endpunkt
 +        http.HandleFunc("/api", HandleProverbJson)
 +
 +        err := http.ListenAndServe(":8000", nil)
 +        if err != nil {
 +                log.Fatal(err)
 +        }
 +}
 +</code>
 +
 +<code html>
 +> ./Webserver_Proverbs &
 +[1] 296083
 +
 +> curl localhost:8000/ ; echo
 +<html>
 + <head></head>
 + <body>
 + <h1>Your Proverb: <a href="https://www.youtube.com/watch?v=PAAkCSZUG1c&amp;t=5m17s">The bigger the interface, the weaker the abstraction.</a></h1>
 + </body>
 +</html>
 +
 +> killall Webserver_Proverbs
 +</code>
 +
 +
 +=== Das Makefile ===
 +
 +<file make Makefile>
 +BINARY = "Webserver_Proverbs"
 +
 +clean:
 +        rm -f ${BINARY}
 +
 +build: clean
 +        go build -o ${BINARY} .
 +</file>
 +
 +
 +==== 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://www.linkedin.com/learning/code-challenges-fur-go/kompakte-programmierratsel-in-go-mit-unterschiedlichen-schwierigkeitsgraden-losen|Code-Challenges für Go]]
  
  
/home/http/wiki/data/attic/go_lernen.1769185726.txt · Zuletzt geändert: von manfred