Ich habe ein Go-Projekt, das zunehmend komplexer wird, und möchte das Dateisystem so gestalten, dass die Schmerzen gelindert werden.
Gibt es einige gute Beispiele dafür, was Sinn macht?
Ich habe ein Go-Projekt, das zunehmend komplexer wird, und möchte das Dateisystem so gestalten, dass die Schmerzen gelindert werden.
Gibt es einige gute Beispiele dafür, was Sinn macht?
Antworten:
Update Mai 2013: Die offizielle Dokumentation befindet sich im Abschnitt " Code Organisation "
Der Go-Code muss in einem Arbeitsbereich aufbewahrt werden .
Ein Arbeitsbereich ist eine Verzeichnishierarchie mit drei Verzeichnissen im Stammverzeichnis:
src
enthält in Paketen organisierte Go-Quelldateien (ein Paket pro Verzeichnis),pkg
enthält Paketobjekte undbin
enthält ausführbare Befehle.Das erstellt
go tool
Quellpakete und installiert die resultierenden Binärdateien in den Verzeichnissenpkg
undbin
.Das
src
Unterverzeichnis enthält normalerweise mehrere Versionskontroll-Repositorys (z. B. für Git oder Mercurial), die die Entwicklung eines oder mehrerer Quellpakete verfolgen.
bin/
streak # command executable
todo # command executable
pkg/
linux_amd64/
code.google.com/p/goauth2/
oauth.a # package object
github.com/nf/todo/
task.a # package object
src/
code.google.com/p/goauth2/
.hg/ # mercurial repository metadata
oauth/
oauth.go # package source
oauth_test.go # test source
Update Juli 2014: siehe " Strukturieren von Anwendungen in Go " von Ben Johnson
Dieser Artikel enthält Tipps wie:
Das Kombinieren der
main.go
Datei und meiner Anwendungslogik in demselben Paket hat zwei Konsequenzen:
- Dadurch wird meine Anwendung als Bibliothek unbrauchbar.
- Ich kann nur eine Anwendungsbinärdatei haben.
Der beste Weg, dies zu beheben, besteht darin, einfach ein "
cmd
" Verzeichnis in meinem Projekt zu verwenden, in dem jedes seiner Unterverzeichnisse eine Anwendungsbinärdatei ist.
camlistore/
cmd/
camget/
main.go
cammount/
main.go
camput/
main.go
camtool/
main.go
Durch Verschieben der
main.go
Datei aus Ihrem Stammverzeichnis können Sie Ihre Anwendung aus der Perspektive einer Bibliothek erstellen. Ihre Anwendungsbinärdatei ist einfach ein Client der Anwendungsbibliothek.Manchmal möchten Sie möglicherweise, dass Benutzer auf mehrere Arten interagieren, sodass Sie mehrere Binärdateien erstellen.
Wenn Sie beispielsweise ein "adder
" -Paket hatten, mit dem Benutzer Zahlen addieren können, möchten Sie möglicherweise sowohl eine Befehlszeilenversion als auch eine Webversion veröffentlichen.
Sie können dies einfach tun, indem Sie Ihr Projekt folgendermaßen organisieren:
adder/
adder.go
cmd/
adder/
main.go
adder-server/
main.go
Benutzer können Ihre "Addierer" -Anwendungsbinärdateien mit "go get" mithilfe eines Auslassungszeichens installieren:
$ go get github.com/benbjohnson/adder/...
Und voila, dein Benutzer hat "
adder
" und "adder-server
" installiert!
Normalerweise sind die Typen meines Projekts alle sehr verwandt, sodass es vom Standpunkt der Benutzerfreundlichkeit und der API aus besser passt.
Diese Typen können auch den Vorteil nutzen, dass sie nicht exportiert werden, wodurch die API klein und übersichtlich bleibt.
- Gruppieren Sie verwandte Typen und Code in jeder Datei. Wenn Ihre Typen und Funktionen gut organisiert sind, liegen die Dateien in der Regel zwischen 200 und 500 SLOC. Das klingt vielleicht nach viel, aber ich finde es einfach zu navigieren. 1000 SLOC ist normalerweise meine Obergrenze für eine einzelne Datei.
- Organisieren Sie den wichtigsten Typ oben in der Datei und fügen Sie unten in der Datei abnehmende Typen hinzu.
- Sobald Ihre Anwendung mehr als 10.000 SLOC erreicht, sollten Sie ernsthaft prüfen, ob sie in kleinere Projekte unterteilt werden kann.
Hinweis: Das letzte Training ist nicht immer gut:
Entschuldigung, ich kann dieser Praxis einfach nicht zustimmen.
Das Trennen des Typs in Dateien hilft bei der Codeverwaltung, der Lesbarkeit, der Wartbarkeit und der Testbarkeit.
Es kann auch die Einzelverantwortung und die Befolgung des Open / Closed-Prinzips sicherstellen.
Die Regel, um eine zirkuläre Abhängigkeit nicht zuzulassen, besteht darin, eine klare Struktur der Pakete zu erzwingen.
(Alternative nur für Februar 2013 src
)
Das klassische Layout finden Sie unter " GitHub-Code-Layout ":
Die App und beide Bibliotheken leben auf Github, jede in ihrem eigenen Repository.
$GOPATH
ist die Wurzel des Projekts - jedes Ihrer Github-Repos wird in mehreren Ordnern unten ausgecheckt$GOPATH
.Ihr Code-Layout würde folgendermaßen aussehen:
$GOPATH/
src/
github.com/
jmcvetta/
useless/
.git/
useless.go
useless_test.go
README.md
uselessd/
.git/
uselessd.go
uselessd_test.go
README.md
Jeder Ordner unter
src/github.com/jmcvetta/
ist das Stammverzeichnis einer separaten Git-Kasse.
Das hat jedoch auf dieser reddit-Seite einige Kritikpunkte hervorgerufen :
Ich empfehle dringend, das Repo nicht so zu strukturieren, wie Sie es haben. Es wird "
go get
" brechen , was eines der nützlichsten Dinge bei Go ist.
Es ist weitaus besser, Ihren Code für Leute zu schreiben, die Go kennen, da sie höchstwahrscheinlich diejenigen sind, die ihn kompilieren.
Und für Leute, die dies nicht tun, werden sie zumindest ein Gefühl für die Sprache bekommen.Legen Sie das Hauptpaket in die Wurzel des Repos.
Haben Sie die Assets in einem Unterverzeichnis (um die Dinge ordentlich zu halten).
Bewahren Sie das Fleisch des Codes in einem Unterpaket auf (falls jemand es außerhalb Ihrer Binärdatei wiederverwenden möchte).
Fügen Sie ein Setup-Skript in das Stammverzeichnis des Repos ein, damit es leicht zu finden ist.Das Herunterladen, Erstellen, Installieren und Einrichten dauert immer noch nur zwei Schritte:
- "
go get <your repo path>
": Lädt den Go-Code herunter und installiert ihn mit einem Unterverzeichnis für die Assets$GOPATH/<your repo path>/setup.sh
: verteilt die Assets an den richtigen Ort und installiert den Service
Ich gehe davon aus, dass Sie mit "Projekt" kein Go-Paket meinen, sondern eine Software, die Sie entwickeln. Ansonsten können Sie hier und hier Hilfe bekommen . Es unterscheidet sich jedoch nicht so sehr vom Schreiben von Paketen für Go: Verwenden Sie Pakete, erstellen Sie einen Ordner für jedes Paket und kombinieren Sie diese Pakete in Ihrer Anwendung.
Um sich eine Meinung zu bilden, können Sie sich die Trend-Go-Repositories auf github ansehen: https://github.com/trending/go . Bemerkenswerte Beispiele sind Cayley und Zeus .
Das beliebteste Schema besteht wahrscheinlich darin, eine Go-Hauptdatei und viele Module und Submodule in ihren eigenen Verzeichnissen zu haben. Wenn Sie viele Metadateien (Dokument, Lizenz, Vorlagen, ...) haben, möchten Sie den Quellcode möglicherweise in ein Unterverzeichnis einfügen. Das habe ich bisher gemacht.
$GOPATH/src
oder unter Verwendung ihrer go get
Tabellennamen.
doozerd
ist kein gutes Beispiel, auch die Tests sind schwach.
Sie sollten sich wahrscheinlich auch dieses Repo ansehen. Es zeigt viele Ideen zur Strukturierung von Go-Anwendungen: https://github.com/golang-standards/project-layout
setup.sh
ist, dass Go einigermaßen plattformübergreifend ist, POSIX-Shell-Skripte jedoch nicht.