Go Home Page
Die Programmiersprache Go

How to Write Go Code — Deutsche Übersetzung

Das Original:
http://golang.org/doc/code.html
© 2009 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_20120115_de.html (Stand: 15.1.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, wie man ein neues Paket erstellt, und wie man Kode testet. Es setzt voraus, dass Sie Go gemäß Installationsanleitung installiert haben.

Bevor Sie loslegen und ein existierendes Paket ändern oder ein neues erstellen, versäumen Sie nicht, eine Mail an die Verteilerliste zu schicken — um uns alle wissen zu lassen, was Sie vorhaben. Das hilft, doppelte Arbeit zu vermeiden, und ermöglicht den Meinungsaustausch über Konzepte, bevor irgendwelcher Kode geschrieben ist.

Gemeinschaft als Ressource

Hilfe in Echtzeit kann man von Teilnehmern bzw. Entwicklern bei #go-nuts auf dem Freenode-IRC-Server erhalten.

Die offizielle Verteilerliste für Diskussionen rund um die Sprache Go ist "Go Nuts".

Fehler kann man melden mithilfe des Go-Problemfolgers [englisch: issue tracker, A.d.Ü].

Für alle, die nahe an der Entwicklung dranbleiben wollen, gibt es eine weitere Verteilerliste, nämlich "golang-checkins", an die bei jedem Einbuchen ins Go-Repositorium eine zusammenfassende Nachricht geht.

Ein neues Paket erstellen

Den Import-Pfadnamen festlegen

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.

Wenn Sie zum Beispiel Ihren Quellkode bei beispiel.com oder code.google.com/p/beispiel geparkt haben, so sollte der Pfadname zu ihren Paket auch mit einer solchen URL beginnen, also: "beispiel.com/eigen/lob" oder "code.google.com/p/beispiel/eigen/lob". Damit kann das go-Kommando automatisch aus dem Importpfad den Quellkode ausbuchen und zusammenbauen.

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

Das go-Kommando und GOPATH

Zum Umwandeln und Installieren von Go-Bibliotheken und Programmen benutzt man in der Regel das go-Kommando. Dieses wird nicht konfiguriert, sondern erkennt allein am Quellkode, was wie zu bauen ist.

Um dieses Werkzeug wirkungsvoll einzusetzen, müssen Sie die GOPATH-Variable setzen. Dort wird eine Liste von Pfaden festgelegt, die den Go-Quellkode und die Binärdateien enthalten. Quellkode, Objektdateien der Pakete und lauffähige Kommandos befinden sich in den Unterverzeichnissen src, pkg und bin des jeweiligen GOPATH-Pfades

GOPATH setzen Sie in der Profildatei Ihres Kommandointerpreters [englisch: shell, A.d.Ü.], also in $HOME/.bshrc, $HOME/.profile oder der Entsprechung auf Ihrem System.

Hier eine Beispielsitzung, in der ein einfaches Paket eigen/lob erzeugt, umgewandelt und installiert wird:

$ export GOPATH=$HOME/gocode
$ mkdir -p $GOPATH/src/eigen/lob
$ cat > $GOPATH/src/eigen/lob/lob.go
package lob
const String = "Go regelt das!"
^D
$ go install eigen/lob
$ ls $GOPATH/pkg/*/eigen
lob.a
		

(^D: Drücken Sie hier Strg + D.)

Mit go help gopath erhalten Sie weitere Information zu GOPATH.

Go-Quelldateien

Die erste Anweisung in einer Go-Quelldatei ist package name, und 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).

Go kompiliert alle Quelldateien eines Pakets auf einmal, so dass man sich ohne besonderen Mechanismus oder Deklarationen auf Konstanten, Variablen und Funktionen in einer anderen Datei beziehen kann.

Wie man sauberen, Go-typischen Kode schreibt, ist hier nicht Thema. Dafür ist "Effective Go" zuständig.

Programme erstellen

Das go-Kommando macht aus Kode mit dem Paketnamen main ein ausführbares Kommando und installiert es im Unterverzeichnis bin des jeweiligen GOPATH-Verzeichnisses.

Ausführbare Kommandos erzeugt man genauso wie Pakete:

$ cat > $GOPATH/src/eigen/rede/rede.go
package main

import (
    "fmt"
    "eigen/lob"
)

func main() {
    fmt.Println(lob.String)
}
^D
$ go install eigen/rede
$ $GOPATH/bin/rede
Go regelt das!

Mit go help install erhalten Sie weitere Information zu Umwandlung und Installation.

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 dann eine Funktion eine Fehlerfunktion wie t.Error oder t.Fail, so gilt der Test als fehlgeschlagen. Weitere Einzelheiten dazu: go help test; und schauen Sie sich die Paket-Doku von testing an.

Um den Test durchzuführen, benutzen Sie go test:

$ cat > $GOPATH/src/eigen/lob/lob_test.go
package lob

import "testing"

func TestString(t *testing.T) {
    const expect = "Go regelt das!"
    if String != expect {
        t.Errorf("String == %q, erwartet wurde: %q", String, expect)
    }
}
^D
$ go test eigen/lob
ok  	eigen/lob

Wenn durch Änderungen die Laufzeit betroffen ist, schreiben Sie eine Benchmark-Funktion und starten sie mit go test -benchmarks=.*. (Schauen Sie nach bei go help testfunc.)

Ein Beispielpaket mit Tests

Dieses Beispielpaket mit Namen numbers besteht aus der Funktion Double, die ein int bekommt und diesen Wert multipliziert mit 2 zurückgibt. Es besteht aus zwei Dateien.

Zuerst die Implementierung, numbers.go:

package numbers

func Double(i int) int {
	return i * 2
}
		

Dann die Tests, numbers_test.go:

package numbers

import (
	"testing"
)

type doubleTest struct {
	in, out int
}

var doubleTests = []doubleTest{
	doubleTest{1, 2},
	doubleTest{2, 4},
	doubleTest{-5, -10},
}

func TestDouble(t *testing.T) {
	for _, dt := range doubleTests {
		v := Double(dt.in)
		if v != dt.out {
			t.Errorf("Double(%d) == %d, erwartet wurde: %d.", dt.in, v, dt.out)
		}
	}
}
		

go install baut und installiert das Paket im Unterverzeichnis pkg des jeweiligen GOPATH-Verzeichnisses; es kann dann von jedem anderen Go-Programm importiert werden.

go test baut das Paket neu, und zwar inclusive der numbers_test.go-Datei, und führt dann die Funktion TestDouble aus. Die Ausgabe "ok" zeigt an, dass alle Tests erfolgreich waren. Wollen Sie sehen, wie fehlgeschlagene Tests gemeldet werden, dann ändern Sie mal den Faktor 2 zu 3.

Weitere Einzelheiten: go help test, go help testfunc und go help testflag; und schauen Sie sich die Paket-Doku von testing an..

Architektur- und betriebssystemspezifischer Kode

Ein Dementi vorweg: Nur die allerwenigsten Go-Pakete sollten auch nur irgendetwas über Hardware oder Betriebssysteme wissen müssen, auf denen sie laufen. In der Regel deckt die Sprache mit ihrer Standardbibliothek die meisten Übertragsbarkeitsprobleme ab. Dieser Abschnitt richtet sich deshalb an erfahrene systemnahe Programmierer, die gute Gründe haben, systemspezifischen Kode zu schreiben, wie zum Beispiel Integration der Assembler-Sprache für schnelle trigonometrische Funktionen, oder Kode, der auf verschiedenen Systemen ein gemeinsames Interface implementiert.

Benutzen Sie zum Kompilieren die Umgebungsvariablen $GOOS und $GOARCH in Ihren Quelldateiennamen.

Angenommen, das Paket mein besteht aus den vier Dateien:

mein.go
mein_386.go
mein_amd64.go
mein_arm.go

Diese beschreiben ein Paket, das für verschiedene Architekturen verschieden gebaut wird, je nach dem $GOARCH im Dateinamen.

Der gemeinsame Kode steht in mein.go während sich architekturspezifischer Kode in mein_386.go, main_amd64.go und main_arm.go befindet.

Solange Sie dieser Parametrisierungskonvention folgen, werden auch Werkzeuge wie das go-Kommando problemlos mit Ihrem Paket zusammenarbeiten:

mein_$(GOOS).go
mein_$(GOARCH).go
mein_$(GOOS)_$(GOARCH).go

Das gilt auch für .s- (Assembler) und für .c-Dateien.