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:
srcenthält Go-Quelldateien,pkgenthält kompilierte Packet-Objekte undbinenthäkt ausführbare Kommandos.
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.
