Go Home Page
Die Programmiersprache Go

How to Write Go Code — Deutsche Übersetzung

Das Original:
http://golang.org/doc/code.html
© 2009-12 The Go Authors
Except as noted, this content is licensed under Creative Commons Attribution 3.0.
Diese Übersetzung:
http://www.bitloeffel.de/DOC/golang/code_20120304_de.html (Stand: 04.03.2012)
© 2011-12 Hans-Werner Heinzen @ Bitloeffel.de
Die Nutzung dieses Dokuments ist unter den Bedingungen der Creative Commons Namensnennung 3.0 erlaubt. Für die verlinkten Quelldateien gelten andere Bestimmungen.

Wie man mit Go arbeitet

Einleitung

Dieses Dokument beschreibt die Schritte zur Entwicklung eines einfachen Go-Pakets, und macht Sie mit dem go-Kommando bekannt, dem Standard-Werkzeug zum Beschaffen, Umwandeln und Installieren von Go-Paketen und Programmen.

Wie man den Quellkode organisiert

GOPATH und Arbeitsbereiche

Eins der wichtigsten Ziele von Go ist, das Programmieren leichter zu machen. Deshalb benutzt das Kommando go weder Makefiles noch andere Einrichtungsdateien. Stattdessen nutzt es die Informationen aus dem Quellkode, um Abhängigkeiten zu erkennen und die Kompilierreihenfolge festzulegen. Das bedeutet: Ihre Erzeugungsskripte ind Ihr Quellkode passen immer zusammen.

Eines müssen Sie tun: Setzen Sie die GOPATH-Umgebungsvariable. GOPATH sagt dem go-Kommando und den damit verbundenen Tools, wo Go-Pakete auf Ihrem System zu finden sind.

GOPATH ist eine Liste von Pfadnamen. Die Syntax entspricht der der PATH-Umgebungsvariablen Ihres Systems. Ein typischer GOPATH für ein Unix-System mag so aussehen:

GOPATH=/home/user/ext:/home/user/mygo

(Auf einem Windows-System benutzen Sie Semikola statt der Doppelpunkte.)

Jeder Pfadname in der Liste (hier also: /home/user/ext und /home/user/mygo) deutet auf den Ort eines Arbeitsbereichs. Ein Arbeitsbereich einthält die Go-Quelldateien sowie die zugehörigen Paketobjekte und ausführbaren Kommandos. Eine Struktur mit den folgenden drei Unterverzeichnissen ist vorgegeben:

Unterverzeichnisse von src enthalten unabhängige Pakete — alle Quelldateien (.go, .c, .h und .s) jedes dieser Unterverzeichnisses sind Elemente des Pakets in diesem Unterverzeichnis.

Schreibt man ein Programm, welches das Paket "widget" importiert, so sucht das go-Kommando zunächst in src/pkg/widget innerhalb des Go-Verzeichnisses, um dann, wenn dort nichts zu finden ist, src/widget nacheinander in allen Arbeitsbereichen zu suchen.

Mit mehreren Arbeitsbereichen erreicht man einiges an Flexibilität, aber jetzt und hier wollen wir uns auf nur einen beschränken.

Gehen wir nun ein einfaches Beispiel durch. Zuerst erzeugen Sie ein Verzeichnis $HOME/meingo und darunter src:

$ mkdir -p $HOME/meingo/src   # ein Verzeichnis für den Quellkode

Setzen Sie als nächstes GOPATH entsprechend. Fügen Sie außerdem das bin-Unterverzeichnis Ihrer PATH-Umgebungsvariablen hinzu, so dass die darin enthaltenen Kommandos ohne den Pfadnamen gestartet werden können. Fügen Sie dazu die folgenden beiden Zeilen zu $HOME/.profile (oder zu einer entsprechenden Datei) hinzu:

export GOPATH=$HOME/meingo
export PATH=$PATH:$HOME/meingo/bin

Import-Pfade

Die Standardpakete haben kurze Namen bekommen wie fmt oder net/http, damit sie bequem zu handhaben sind. Für Ihr eigenes Projekt wählen Sie bitte einen Namen, der wahrscheinlich nicht mit zukünftigen Standardpaketen oder anderen, externen Bibliotheken kollidiert.

Die beste Wahl für einen Import-Pfadnamen ist wohl die Adresse Ihres Versionskonroll-Repositoriums. Befindet sich beispielsweise Ihr Repositorium unter beispiel.com oder code.google.com/p/beispiel, so sollten die Paket-Pfadnamen mit dieser URL beginnen, also etwa "beispiel.com/irgend/was" oder "code.google.com/p/beispiel/irgend/was". Halten Sie sich an diese Konvention, so kann das Kommando go anhand des Pfadnamens automatisch Ihren Quellkode ausbuchen und umwandeln.

Wenn Sie Ihren Kode nicht auf diese Weise installieren wollen, dann sorgen Sie zumindest für einen eindeutigen Präfix wie es "irgendwo/" in "irgendwo/irgend/was" einer ist. Gut wäre z.B. Ihr Firmen- oder Projektname — der wird von anderen wahrscheinlich nicht benutzt.

Hier wollen wir beispiel/ für unseren Importpfad benutzen:

$ mkdir -p $GOPATH/src/beispiel

Paketnamen

Die erste Anweisung in einer Go-Quelldatei sollte sein:

package name

name ist der Standardname des Pakets fürs Importieren. (Alle Dateien eines Pakets müssen denselben Namen benutzen.)

Eine Go-Konvention besagt, dass der Paketname gleich dem letzten Teil des Importpfads ist: ein Paket, das als "crypto/rot13" importiert wird, sollte auch rot13 heißen. Die Paketnamen in den Quellen für eine Binärdatei müssen nicht eindeutig sein, sondern nur die Import-Pfade (die Langnamen der Dateien).

Legen Sie nun ein neues Paket namnes newmath unter beispiel/ an:

$ cd $GOPATH/src/beispiel
$ mkdir newmath

Legen Sie dort eine Datei namens $GOPATH/src/beispiel/newmath/sqrt.go, die folgenden Go-Kode enthält:

// Paket newmath ist ein einfaches Beispielpaket.
package newmath

// Sqrt gibt eine Näherung der Quadratwurzel von x zurück.
func Sqrt(x float64) float64 {
    // Diese Implementierung ist nicht gut.
    // Echte Programme sollten "math" importieren und math.Sqrt benutzen.
    z := 0.0
    for i := 0; i < 1000; i++ {
        z -= (z*z - x) / (2 * x)
    }
    return z
}

Das Paket kann importiert werden über den Teil des Verzeichnis-Pfadnamens hinter src/, also so:

import "beispiel/newmath"

In Effective Go finden Sie mehr über Namenskonventionen in Go.

Umwandeln und Installieren

Das go-Kommando versteht verschiedene Unterkommandos, deren wichtigstes install heißt. Startet man go install importpath, so wird ein Paket umgewandelt und installiert.

"Ein Paket installieren" bedeutet, dass die Objektdatei bzw. die lauffähige Binärdatei des Pakets ins pkg- bzw. bin-Unterverzeichnis des Arbeitsbereichs geschrieben wird, in dem sich auch die Quelldateien befinden.

Ein Paket umwandeln

Um ein Paket umzuwandeln und zu installieren, schreiben Sie:

$ go install beispiel/newmath

Dieses Kommando gibt keine Meldung aus, wenn das Paket inclusive der Teile, von denen es abhängt, fehlerfrei umgewandelt und installiert wurden.

Wird dem Kommando kein Import-Pfadname mitgegeben, so nimmt go das aktuelle Verzeichnis. Die folgenden Kommandos haben dengleichen Effekt wie das oben genannte:

$ cd $GOPATH/src/beispiel/newmath
$ go install

Der Verzeichnisbaum des Arbeitsbereichs wird danach so aussehen (angenommen, wir befinden uns unter Linux auf einem 64-Bit-System):

pkg/
    linux_amd64/
        beispiel/
            newmath.a  # Paket-Objektdatei
src/
    beispiel/
        newmath/
            sqrt.go    # Paket-Quelldatei

Ein Kommando umwandeln

Das go-Kommando behandelt Kode, der zum Paket main gehört, als ausführbares Kommando und installiert die Binärdatei ins Unterverzeichnis bin des GOPATH-Verzeichnisses.

Fügen Sie nun ein Kommando namens hallo zum Quellverzeichnis hinzu. Zunächst erzeugen Sie also das beispiel/hallo-Verzeichnis:

$ cd $GOPATH/src/beispiel
$ mkdir hallo

Dann legen Sie dort eine Datei namens $GOPATH/src/beispiel/hallo/hallo.go an, mit folgendem Inhalt:

// Hallo ist ein einfaches Beispiel für ein main-Paket.
package main

import (
    "beispiel/newmath"
    "fmt"
)

func main() {
    fmt.Printf("Hallo, Ihr da. Die Quadratwurzel aus 2 ist %v.\n", newmath.Sqrt(2))
}

Anschließend starten Sie go install, wodurch die Binärdatei in $GOPATH/bin installiert wird:

$ go install beispiel/hallo

Dann starten Sie das Programm, wie jedes andere Kommando auch:

$ $GOPATH/bin/hallo
Hallo, Ihr da. Die Quadratwurzel aus 2 ist 1.414213562373095.

Hatten Sie $HOME/meingo/bin Ihrem PATH angefügt, können Sie beim Aufruf auf den Pfad verzichten:

$ hallo
Hallo, Ihr da. Die Quadratwurzel aus 2 ist 1.414213562373095.

Der Verzeichnisbaum des Arbeitsbereichs wird jetzt so aussehen:

bin/
    hallo              # Komando-Binärdatei
pkg/
    linux_amd64/
        beispiel/
            newmath.a  # Paket-Objektdatei
src/
    beispiel/
        hallo/
            hallo.go   # Kommando-Quelldatei
        newmath/
            sqrt.go    # Paket-Quelldatei

Das go-Kommando kennt auch ein Unterkommando build, welches wie install arbeitet, nur dass alle Objekte in einem temporären Verzeichnis gehalten werden und nicht unter pkg oder bin. Wird ein Kommando gebaut, so wird eine Binärdatei, benannt nach dem letzten Teil des Importpfades, ins aktuelle Verzeichnis geschrieben. Wird ein Paket gebaut, so wandelt go build nur um, um zu testen, ob erfolgreich umgewandelt werden kann; die Objektdatei des Pakets landet im Biteimer.

Testen

Go besitzt einen leichtgewichtigen Testrahmen, der aus dem go-Kommando und dem Paket testing besteht.

Einen Test schreiben Sie, indem Sie eine Datei erzeugen, deren Namem mit _test.go endet, und die Funktionen enthält mit Namen wie TestXXX und der Signatur func (t *testing.T). Der Testrahmen startet jede dieser Funktionen. Ruft eine Funktion eine Fehlerfunktion wie t.Error oder t.Fail, so gilt der Test als fehlgeschlagen.

Fügen Sie dem Paket newmath einen Test hinzu, indem Sie eine Datei folgenden Inhalts erzeugen:

package newmath

import "testing"

func TestSqrt(t *testing.T) {
	const in, out = 9, 3
	if x := Sqrt(in); x != out {
		t.Errorf("Quadratwurzel(%v) IST: %v, SOLL: %v" , in, x, out)
        }
}

Starten Sie jetzt den Test mit go test:

$ go test beispiel/newmath
ok  	beispiel/newmath

Für weitere Einzelheiten tippen Sie go help test, und schauen Sie nach in der testing-Paketdokumentation.

Ferne Pakete

Ein Import-Pfadname kann festlegen, wie man Paket-Quellkode von einem Versionskontrollsystem wie Git oder Mercurial bekommt. Das go-Kommando benutzt das, um automatisch Pakete von entfernten Repositorien abzuholen. Zum Beispiel sind die in diesem Aufsatz beschriebenen Beispiele in einem Mercurial-Repositorium bei Google Code hinterlegt, nämlich code.google.com/p/go.example. Wenn Sie die URL des Repositoriums im Import-Pfadnamen des Pakets mit angeben, so wird go get es automatisch abholen, umwandeln und installieren:

$ go get code.google.com/p/go.example/hello
$ $GOPATH/bin/hello
Hello, world.  Sqrt(2) = 1.414213562373095

Befindet sich das gewünschte Paket nicht in einem Arbeitsbereich, so plaziert go get es im ersten Arbeitsbereich, den GOPATH nennt. (Existiert das Paket bereits, so überspringt go get das Abholen, und verhält sich ansonsten so wie go install.)

Im Anschluss an das obige go get-Kommando, wird der Arbeitsbereich so aussehen:

bin/
    hallo                 # Komando-Binärdatei
    hello                 # Komando-Binärdatei
pkg/
    linux_amd64/
        beispiel/
            newmath.a     # Paket-Objektdatei
        code.google.com/p/go.example/
            newmath.a     # Paket-Objektdatei
src/
    beispiel/
        hallo/
            hallo.go      # Kommando-Quelldatei
        newmath/
            sqrt.go       # Paket-Quelldatei
            sqrt_test.go  # Test-Quelldatei
    code.google.com/p/go.example/
        hello/
            hello.go      # Kommando-Quelldatei
        newmath/
            sqrt.go       # Paket-Quelldatei
            sqrt_test.go  # Test-Quelldatei

Das hello-Kommando, das bei Google Code hinterlegt ist, hängt ab vom Paket newmath im gleichen Repositorium. Die Import-Anweisung in der Datei hello.go hält sich an diegleiche Import-Pfadnamen-Konvention, so dass es für go get möglich ist, das entsprechende Paket zu lokalisieren und ebenfalls zu installieren:

import "code.google.com/p/go.example/newmath"

Das Einhalten dieser Konvention ist der wohl einfachste Weg, Ihre Go-Pakete anderen zugänglich zu machen. Das Go Package Dashboard zeigt eine Liste der kürzlich mit dem go-Kommando installierten Pakete.

Für weitere Einzelheiten über das Benutzen von entfernten Repositorien mit dem go-Kommando, siehe go help remote.

Weiterer Lesestoff

Lesen Sie in Effective Go, wie man klaren, typischen Go-Kode schreibt.

Machen sie A Tour of Go, um Go richtig kennenzulernen.

Besuchen Sie die Dokumentationsseite. Dort finden Sie in die Tiefe gehende Aufsätze über die Sprache Go, ihre Bibliotheken und ihre Werkzeuge.