Programmiersprache Go

5. Dezember 2024

Lang: cs en de es

Vor kurzem habe ich die Programmiersprache Go ausprobiert. Und ich habe ChatGPT benutzt, um einige Beispiele zu generieren. Ich habe diese Beispiele auf github hochgeladen und eine Beschreibung erstellt, wie man die Beispiele ausprobieren kann. Laut dem anleitung in diesem Artikel können Sie auch die Programmiersprache Go ausprobieren.

In der sich schnell verändernden Welt der Technologie zählen Einfachheit, Geschwindigkeit und Skalierbarkeit mehr denn je, ist die Programmiersprache Go sehr beliebt geworden. Go (oder Golang) wurde von Google entwickelt. Die Sprache Go kombiniert einen modernen Ansatz zur Programmierung mit einem Minimum an unnötiger Komplexität. Sie bietet Funktionen wie einfache parallele Programmierung, robuste Speicherverwaltung und eine minimalistische Syntax, ist sie besonders beliebt bei der Entwicklung von Webanwendungen, Microservices und Cloud-Lösungen.

Grundlegende Eigenschaften von Go

  • Einfachheit und Klarheit

    Go legt Wert auf eine einfache und klare Syntax, die das Lesen und Schreiben von Code erleichtert. Es enthält eine minimale Menge an Schlüsselwörtern, was die Komplexität des Lernens reduziert.

  • Statisch typisierte Sprache

    Go ist statisch typisiert, was bedeutet, dass die Typen der Variablen zur Kompilierzeit bekannt sind, was bei der Fehlererkennung hilft. bei der Fehlererkennung.

  • Schnelle Kompilierung

    Go ist so konzipiert, dass der Code sehr schnell kompiliert wird, was die Entwicklung und den Einsatz beschleunigt.

  • Eingebaute Unterstützung für Parallelität

    Go hat native Unterstützung für Gorutins und Channels, die es einfach machen, parallele und konkurrierende Programmierung. Gorutins sind leichtgewichtige Thread-Einheiten, die gleichzeitig laufen können.

    >
  • Automatische Speicherverwaltung (Garbage Collection)

    Go hat einen eingebauten Garbage Collector, der automatisch den Speicher verwaltet und unbenutzte Objekte freigibt.

  • Einfaches Paketsystem

    Go verfügt über ein minimalistisches Paketverwaltungssystem, das das Importieren und Organisieren von Bibliotheken erleichtert.

  • Starke Standardbibliothek

    Go enthält eine starke Standardbibliothek, die Funktionen für die Arbeit mit Netzwerken, Dateien, Verschlüsselung, Webservern und anderen allgemeinen Aufgaben bietet.

  • Plattformübergreifende Portabilität

    Go macht es einfach, Anwendungen auf verschiedenen Plattformen (Linux, macOS, Windows) zu kompilieren, dank der Unterstützung für Cross-Compilation.

  • Starke Toolchain

    Go bietet eingebaute Werkzeuge für Code-Formatierung (gofmt), statische Analyse, Testen und Benchmarking.

  • Keine Ausnahmen

    Go verwendet keine traditionellen Ausnahmen für das Fehlermanagement. Stattdessen verwendet es Rückgabewerte und das Idiom der "Fehlerbehandlung", was zu einer expliziten Fehlerbehandlung führt.

  • Sicherheit bei paralleler Ausführung

    Go minimiert das Risiko von Race Conditions durch Konstrukte wie Channels, die einen sicheren Datenaustausch zwischen gorutinas.

  • Minimalismus durch Design

    Go hat einige Funktionen entfernt, die in anderen Sprachen üblich sind (z.B. Vererbung, Generika - diese wurden erst in Go 1.18 hinzugefügt, aber immer noch auf eine minimalistische Weise).

Go ist ideal für die Entwicklung von Webservern, Microservice-Architekturen, Netzwerkanwendungen und anderen modernen verteilte Systeme.

Installation

Auf einer normalen Linux-Distribution ist die Installation von Go einfach über das peg System.

In der Linux-Distribution Magei wird mit diesem Befehl Go installiert:

urpmi golang

Für Windows und Mac können Sie den Go-Sprachinstaller aus dem Internet herunterladen.

Hallo Wort

Das grundlegende Beispiel ist das Drucken von Text.
Der folgende Code in Go gibt den Text "Hello, World!" auf der Konsole aus. Er verwendet das Paket fmt, um den Text auszugeben und fmt.Println Funktion, um die Nachricht anzuzeigen. Die Funktion main ist der Einstiegspunkt des Programms, der automatisch ausgeführt wird, wenn das Programm ausgeführt wird.

Paket main

import "fmt"

func main() {
    fmt.Println("Hallo, Welt!")
}

Um das Programm zu kompilieren, verwenden Sie go build . oder go build hello.go. und führen Sie dann die erzeugte Binärdatei ./hello aus.
Oder geben Sie einen Befehl ein, der sowohl kompiliert als auch ausgeführt wird go run . oder go run hello.go.

programming-language-go-examples

Web-Server

Dieser Code lässt einen einfachen Webserver auf Port 8080 laufen. Jede eingehende Anfrage an den Wurzelpfad (/) wird von der Funktion handler bearbeitet, die mit einer Nachricht antwortet, die den angeforderten URL-Pfad enthält. Der Server verwendet http.HandleFunc, um diese Funktion zuzuweisen, und wird ausgelöst durch http.ListenAndServe. Wenn der Server nicht startet, gibt das Programm einen Fehler aus und beendet sich.

Hauptpaket

import (
	"fmt"
	"log"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hallo, Sie haben angefordert: %s\n", r.URL.Path)
}

func main() {
	http.HandleFunc("/", handler)

	fmt.Println("Starte Server an Port 8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}


Parallelität - Threads

Dieser Code zeigt, wie man in Go mit gorutin Aufgaben parallel laufen lässt und wie man ihre Fertigstellung mit sync.WaitGroup synchronisiert.

Paket main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

// Eine langlaufende Aufgabe simulieren
func longRunningTask(id int, wg *sync.WaitGroup) {
	wg.Done() aufschieben

	// Zufällige Bearbeitungszeit zwischen 1-3 Sekunden simulieren
	duration := time.Duration(rand.Intn(3)+1) * time.Second
	fmt.Printf("Aufgabe %d gestartet, dauert %v\n", id, Dauer)

	time.Sleep(duration) // Verarbeitung simulieren
	fmt.Printf("Aufgabe %d beendet\n", id)
}

func main() {
	rand.Seed(time.Now().UnixNano())

	// Sync-Gruppe, die auf die Fertigstellung aller Daten wartet
	var wg sync.WaitGroup

	// Anzahl der parallelen Aufgaben
	numTasks := 5

	// Parallele Ausführung von Aufgaben mit gorutin
	for i := 1; i <= numTasks; i++ {
		wg.Add(1)
		go longRunningTask(i, &wg)
	}

	// Warten auf die Fertigstellung aller Aufgaben
	wg.Wait()

	fmt.Println("Alle Aufgaben abgeschlossen")
}

REST API

Was ist eine Rest-API?
REST API (Representational State Transfer Application Programming Interface) ist ein Architekturstil für die Entwicklung von Netzwerkanwendungen, der Standard-HTTP-Methoden wie GET, POST, PUT, DELETE für die Kommunikation zwischen Client und Server verwendet. REST-API Ermöglicht Clients den Zugriff auf Daten und Operationen auf dem Server über einen Uniform Resource Locator (URL) und bietet eine Trennung von Client- und Serverlogik. Die API arbeitet auf der Grundlage von Prinzipien wie zustandslos (jede Anfrage (jede Anfrage ist unabhängig) und verwendet Formate wie JSON oder XML für den Datenaustausch, wodurch eine einfache Integration zwischen verschiedenen Systemen.

Wenn Sie die Programmiersprache PHP verwenden, dann ist eine ausgezeichnete Wahl, um sie zum Laufen zu bringen REST API's API platform, die eine Bibliothek für Symfony ist und auf Doctrine aufbaut.

Hier ist ein Beispiel für Code in Go, der die REST-API implementiert. Der folgende Code implementiert die RESTful-API in Go für die Verwaltung von Elementen. Er verwendet das Paket gorilla/mux, um um HTTP-Anfragen weiterzuleiten. Die Anwendung ermöglicht CRUD-Operationen (Erstellen, Lesen, Aktualisieren und Löschen) auf Elemente, die im Speicher in memoryStore Karte gespeichert sind. Jedes Element hat eine eindeutige ID, einen Namen und einen Wert. Der Code implementiert verschiedene Endpunkte zum Abrufen aller Elemente (/items), einzelne Einträge nach ID abzurufen (/items/{id}), einen neuen Eintrag zu erstellen, einen vorhandenen Eintrag zu aktualisieren und einen Eintrag zu löschen. Verwendet die sync.Mutex Synchronisationssperre um einen sicheren Zugriff auf die Daten zu gewährleisten.

Paket main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"sync"

	"github.com/gorilla/mux"
)

// go get -u github.com/gorilla/mux
Typ Item struct {
	ID int `json: "id"`
	Name string `json: "name"`
	Wert string `json: "value"`
}

var (
	memoryStore = make(map[int]Item)
	idZähler = 1
	mu sync.Mutex
)

func getItems(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	aufschieben mu.Unlock()

	var items []Item
	for _, item := range memoryStore {
		items = append(items, item)
	}
	json.NewEncoder(w).Encode(items)
}

func getItem(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	aufschieben mu.Unlock()

	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

	item, exists := memoryStore[id]
	if !exists {
		http.Error(w, "Element nicht gefunden", http.StatusNotFound)
		return
	}
	json.NewEncoder(w).Encode(item)
}

func createItem(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	aufschieben mu.Unlock()

	var item Item
	_ = json.NewDecoder(r.Body).Decode(&item)
	item.ID = idCounter
	idZähler++
	memoryStore[item.ID] = item
	json.NewEncoder(w).Encode(item)
}

func updateItem(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	aufschieben mu.Unlock()

	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

	_, exists := memoryStore[id]
	if !exists {
		http.Error(w, "Element nicht gefunden", http.StatusNotFound)
		return
	}

	var updatedItem Item
	_ = json.NewDecoder(r.Body).Decode(&updatedItem)
	updatedItem.ID = id
	memoryStore[id] = updatedItem
	json.NewEncoder(w).Encode(updatedItem)
}

func deleteItem(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	aufschieben mu.Unlock()

	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

	_, exists := memoryStore[id]
	if !exists {
		http.Error(w, "Element nicht gefunden", http.StatusNotFound)
		return
	}
	delete(memoryStore, id)
	w.WriteHeader(http.StatusNoContent)
}

func main() {
	Router := mux.NewRouter()

	// Endpunkte für REST-API
	router.HandleFunc("/items", getItems).Methods("GET")
	router.HandleFunc("/items/{id}", getItem).Methods("GET")
	router.HandleFunc("/items", createItem).Methods("POST")
	router.HandleFunc("/items/{id}", updateItem).Methods("PUT")
	router.HandleFunc("/items/{id}", deleteItem).Methods("DELETE")

	fmt.Println("Server läuft auf Port 8080")
	log.Fatal(http.ListenAndServe(":8080", router))
}

Nachdem Sie diese Anwendung ausgeführt haben, wird auf Ihrem Computer ein Webserver auf dem Port 8080 laufen. Sie können also die URL http://localhost:8080/ in Ihren Webbrowser eingeben.
Für andere Anwendungen, bei denen Sie HTTP-Anfragen mit Daten senden müssen, können Sie z. B. das Konsolentool .curl.

Neues Element erstellen:

curl -X POST http://localhost:8080/items -H "Content-Type: application/json" -d '{"name": "Item1", "value": "Value1"}'

Alle Elemente auflisten:

http://localhost:8080/items

Element mit ID 1 anzeigen:
http://localhost:8080/items/1.

Aktualisieren Sie die Element-ID 1:
curl -X PUT http://localhost:8080/items/1 -H "Content-Type: application/json" -d '{"name": "UpdatedItem1", "value": "UpdatedValue1"}'

Deltete item ID 1:
curl -X DELETE http://localhost:8080/items/1

GUI-Anwendungen

In der Sprache Go ist es auch möglich, Anwendungen mit einer grafischen Benutzeroberfläche zu erstellen.
programming-language-go-gui

Hier ist ein kleines Beispiel für eine grafische Anwendung. Der folgende Code erstellt eine einfache grafische Anwendung in Go unter Verwendung der Qt-Bibliothek. Die Anwendung erstellt ein Hauptfenster mit mit dem Titel "Go Qt Example" und einer Mindestgröße von 400x300 Pixeln. Innerhalb des Fensters befindet sich eine "Click Me!"-Schaltfläche, die wenn sie angeklickt wird, eine Informationsmeldung mit dem Text "Schaltfläche angeklickt!" anzeigt. Die Anwendung verwendet ein Layout, um die Schaltfläche zu platzieren und setzt dieses Layout auf das zentrale Widget. Dann wird das Hauptfenster angezeigt, die Anwendung wird gestartet und wartet auf die Benutzerinteraktion.

Paket main

import (
	"wasp"

	"github.com/therecipe/qt/widgets"
)

func main() {
	// Erstellen einer neuen Qt-Anwendung
	app := widgets.NewQApplication(len(os.Args), os.Args)

	// Erstellen des Hauptfensters
	window := widgets.NewQMainWindow(nil, 0)
	window.SetWindowTitle("Go Qt Example")
	window.SetMinimumSize2(400, 300)

	// Ein zentrales Widget und Layout erstellen
	centralWidget := widgets.NewQWidget(nil, 0)
	Layout := widgets.NewQVBoxLayout()

	// Schaltfläche erstellen
	Schaltfläche := widgets.NewQPushButton2("Klick mich!", nil)
	button.ConnectClicked(func(bool) {
		widgets.QMessageBox_Information(nil, "Message", "Schaltfläche geklickt!", widgets.QMessageBox__Ok, widgets.QMessageBox__Ok)
	})

	// Hinzufügen einer Schaltfläche zum Layout
	layout.AddWidget(Schaltfläche, 0, 0)

	// Festlegen des Layouts für das zentrale Widget
	centralWidget.SetLayout(layout)

	// Das zentrale Widget auf das Hauptfenster setzen
	window.SetCentralWidget(centralWidget)

	// Das Fenster anzeigen
	window.Show()

	// Starten Sie die Anwendung
	app.Exec()
}

Was ist eine go.mod-Datei

Eine go.mod-Datei ist eine Datei in der Sprache Go, die ein Modul und seine Abhängigkeiten definiert. Ein Modul ist eine Sammlung von Paketen, die versioniert sind und in anderen Projekten verwendet werden können. Die go.mod-Datei gibt den Namen des Moduls, die Go-Version und alle anderen Abhängigkeiten an, die das Modul benötigt.

Inhaltsbeispiele:

modul github.com/benutzername/projekt

go 1.20

require (
    github.com/some/dependency v1.2.3
    golang.org/x/tools v0.1.5
)

Quellcodes

Alle Quellcodes für die Beispiele in der Programmiersprache Go sind verfügbar auf github verfügbar. Klonen Sie einfach das Repository und Sie können die Anwendungen ausprobieren.

Video-Tutorial

Video und verbale Beschreibungen für Go-Anwendungsbeispiele

Fehlerbehandlung

Go verwendet keine traditionellen Ausnahmen für die Fehlerbehandlung. Stattdessen verwendet es Rückgabewerte und das Idiom der "Fehlerbehandlung". Was bedeutet das?

Die Sprache Go (Golang) verfolgt einen anderen Ansatz zur Fehlerbehandlung als viele andere Programmiersprachen. Unter Gegensatz zu Sprachen wie Java, Python oder C#, die Ausnahmen verwenden, benutzt Go Rückgabewerte.

Was bedeutet das konkret:

  1. Keine Ausnahmen:

    Go verfügt nicht über einen Mechanismus zum Auslösen und Abfangen von Ausnahmen (z.B. try-catch-Blöcke). Stattdessen geben Funktionen in Go typischerweise zwei Werte zurück:

    • Das Hauptergebnis der Funktion.
    • Ein Fehler als Wert vom Typ Fehler.
  2. Idiomatischer Ansatz der "Fehlerbehandlung":

    Fehler werden explizit behandelt, zum Beispiel:

    
    Paket main
    
    import (
        "fmt"
        "wasp"
    )
    
    func main() {
        Datei, err := os.Open("Beispiel.txt")
        if err != nil {
            fmt.Println("Fehler:", err)
            return
        }
        defer file.Close()
    
        fmt.Println("Datei erfolgreich geöffnet")
    }
    
                

    In diesem Beispiel:

    • os.Open gibt zwei Werte zurück: die geöffnete Datei (*os.File) und einen Fehler (Fehler), wenn die Datei nicht geöffnet werden kann.
    • Der Code prüft, ob err nicht nil ist, was bedeutet, dass ein Fehler aufgetreten ist.
  3. Vorteile dieses Ansatzes:
    • Einfachheit: Der Code ist besser lesbar und weniger magisch, weil die Fehlerlogik explizit ist.
    • Kontrolle: Die Entwickler haben eine klare Kontrolle darüber, wie Fehler behandelt werden.
    • Sicherheit: Keine "versteckten" Ausnahmen, die durchschlüpfen könnten.
  4. Nachteile:
    • Mehr Code: Der Code kann ausführlicher sein, da jeder Funktionsaufruf oft eine Fehlerprüfung erfordert.
    • Notwendigkeit von Disziplin: Entwickler müssen Fehler immer korrekt abfangen und behandeln, sonst können sie ignoriert werden.

Dieser Ansatz spiegelt die Philosophie von Go wider, die Einfachheit und Vorhersagbarkeit komplexeren Mechanismen wie Ausnahmen.

Bewertung der Sprache Go

Persönlich sehe ich den Vorteil der Programmiersprache Go darin, dass man eine Anwendung einfach auf Linux entwickeln und dann die Anwendung für eine andere Plattform croc-kompilieren und die Binärdatei einfach hochladen und dort ausführen. Wenn Sie eine plattformübergreifende Grafikbibliothek wie QT verwenden, können Sie problemlos grafische Anwendungen auf Linux entwickeln, die der Kunde dann auf Windows oder Mac OS ausführen kann. zum Beispiel auf Windows oder Mac OS.
Eine explizite Fehlerbehandlung macht die Anwendung stabiler und sicherer. Wenn also nicht die Schnelligkeit im Vordergrund steht Entwicklung, sondern Stabilität und Sicherheit, dann eignet sich statt PHP die Sprache Go. Oder . verwenden Sie die Rust sichere Sprache.
Für diejenigen, die parallele Anwendungen programmieren müssen, eignet sich die Sprache Go als einfaches Werkzeug, mit dem einfach funktionale Anwendungen zu erstellen, die parallel laufen.

Artikel zu einem ähnlichen Thema

Python-Programm zur Steuerung von Docker über die API
Wie man MailCatcher zum Testen von E-Mails verwendet
Python OpenAI API
Erstellen einer WebSocket-Webanwendung und Einrichten eines Proxys
Projektmanagement: agile Softwareentwicklung
Wie man alte PHP-Anwendungen ausführt
Was ein guter Programmierer wissen sollte
Programmiersprache Rust
NodeJS: Entwicklung, Serverkonfiguration
Nette Sicherheitslücke CVE-2020-15227
REST API: Plattform-API
Kundenspezifisches Web- und E-Mail-Hosting mit ISP Config-Software
Programmierung in SQL: PostgreSQL, MySQL/MariaDB
HTTPS: sicheres Web
NoSQL-Datenbank Mongo DB
Herstellen einer Verbindung zu Microsoft SQL Server unter Linux
Was ist die Stellenbeschreibung eines Programmierers?
Lokalisierung von Python-Anwendungen
Welches Mail- und Webhosting Sie wählen sollten
Digispark - Atmel ATtiny Mikrocontroller mit Arduino IDE programmieren
Entwicklung für ARM-Prozessoren mit Arduino IDE
Wie programmiere ich den ESP8266 WiFi-Prozessor?
Offenes Smartphone mit Linux - Openmoko Neo FreeRunner

Newsletter

Wenn Sie daran interessiert sind, gelegentlich Neuigkeiten per E-Mail zu erhalten.
Sie können sich registrieren, indem Sie Ihre E-Mail-Adresse eingeben News-Abonnement.


+