2014-06-20 24 views
10

Stavo cercando di capire come funzionano i pacchetti in modo migliore in termini di cosa effettivamente fa golan piuttosto che cosa è di solito fatto o considerato una buona pratica (possiamo parlare anche di buone pratiche più avanti, ma vorrei per capire andare prima).Come funzionano i pacchetti in golang

Da effective go dice:

"Un'altra convenzione è che il nome del pacchetto è il nome di base della sua directory sorgente ..."

Tuttavia, la descrizione di cui sopra non sembra essere forzato di andare o richiesto. Quindi, mi chiedevo se mi fosse stato permesso di avere più file con diverse dichiarazioni di pacchetto nella parte superiore della directory stessa. Se sono autorizzato ad avere più dichiarazioni di pacchetti nella stessa directory, come posso quindi importarle e usarle separatamente nello stesso file? Fondamentalmente, immagino che uno dei problemi che ho è dovuto alla formulazione di alcuni dei tutorial/documentazione di go. Se è per convenzione, allora per me, è implicito che sia NON applicato dalla lingua. Perché, ad esempio, i programmatori non scrivono la parola chiave func per una funzione per convenzione. Scriviamo func perché altrimenti andrà a urlare contro di voi e sarà non compilare. Pertanto, desidero chiarire questo con l'esempio seguente (e se possibile modificare la documentazione per il go, perché questo è un grosso problema secondo me, come può essere fatto?).

Per esempio dire che ho tre file di A.go, B.go, C.go che stampa una funzione di stampa Print() che stampa semplicemente a, b, c, rispettivamente. Sono tutti sulla stessa directory di base chiamata forse base. Quindi ognuno ha una dichiarazione del pacchetto diversa package Apkg, package Bpkg, package Cpkg.

come vorresti poi importarli? Qualcosa come segue funziona?

package main 

import(
    nameA "github.com/user_me/base/Apkg" 
    nameB "github.com/user_me/base/Bpkg" 
    nameC "github.com/user_me/base/Cpkg" 
) 

func main() { 
    nameA.Print() \\prints a 
    nameB.Print() \\prints b 
    nameC.Print() \\prints c 
} 

o forse non abbiamo nemmeno bisogno di specificare il nome, se le statments pacchetto sono la parte superiore sono già diversi:

package main 

import(
    "github.com/user_me/base" 
) 

func main() { 
    Apkg.Print() \\prints a 
    Bpkg.Print() \\prints b 
    Cpkg.Print() \\prints c 
} 

il file di stampa sono:

A.go:

//file at github.com.user_me/base and name A.go 
package Apkg 

import "fmt" 

func Print(){ 
    fmt.Println("A") 
} 

B.go:

//file at github.com.user_me/base and name B.go 
package Bpkg 

import "fmt" 

func Print(){ 
    fmt.Println("B") 
} 

C.go: // file alla pacchetto github.com.user_me/base e il nome C.go Cpkg

import "fmt" 

func Print(){ 
    fmt.Println("C") 
} 

Inoltre, se si può avere un nome diverso dal base , qualcuno potrebbe chiarirmi come viene effettivamente effettuata l'importazione? Se il nome del pacchetto è package Apkg in base, l'importazione deve essere import github.com/user_me/base o import github.com/user_me/base/Apkg o github.com/user_me/Apkg.

Non l'ho ancora testato ma lo farò presto.L'accordo di importazione in corso è stato un po 'di confusione per me e mi piacerebbe ricevere una risposta e condividerla con il mondo.

risposta

7

No, è 1 pacchetto per cartella, in modo che avrebbe dovuto averli:

$GOPATH/src/github.com/user_me/base/Apkg/a.go 
$GOPATH/src/github.com/user_me/base/Bpkg/b.go 
$GOPATH/src/github.com/user_me/base/Cpkg/c.go 

non si può nemmeno costruirlo altrimenti:

┌─ [email protected] [/t/blah]                           
└──➜ go build 
can't load package: package .: found packages pkgA (blah1.go) and pkgB (blah2.go) in /tmp/blah 

vostro vostro nome del pacchetto non lo fa è necessario avere lo stesso nome della directory in cui si trovano, tuttavia tutti i file in una directory devono avere lo stesso nome del pacchetto.

Inoltre, è possibile rinominare i pacchetti durante l'importazione, ad esempio:

import (
    cr "crypto/rand" 
    mr "math/rand" 
) 

O il vostro libreria si chiama principale (cattiva idea btw):

import m "github.com/user_me/base/main" 
+0

Quindi non è buono "convenzione", la il linguaggio lo applica? –

+0

Sì, per esempio controlla l'aggiornamento – OneOfOne

+0

Interessante che lo esprimano in un modo così strano dicendo la sua "convenzione" se la lingua lo impone. Il motivo per cui ero scettico e confuso su questo era perché in precedenza avevo un nome di pacchetto nella parte superiore dei miei file per 'base' che NON corrispondeva al nome della directory di base. Quindi, ad esempio, avevo "pacchetto superBase" piuttosto che "pacchetto base" ed ero ancora in grado di eseguire "go test" anche se la mia importazione era "import baseNome github.com/user_me/base" ma il pacchetto per ogni file era 'pacchetto superBase'. Strano. E 'una cosa speciale su go test? –