Lär dig mer om paket
Paket i Go är som bibliotek eller moduler på andra programmeringsspråk. Du kan paketera koden och återanvända den någon annanstans. Källkoden för ett paket kan distribueras i mer än en .go
fil. Hittills har vi skrivit main
paketet och gjort några referenser till andra interna paket.
I det här avsnittet får du lära dig vad ett paket är. Du får också lära dig hur du skapar ett och hur du använder externa paket.
Huvudpaket
Som du kanske har märkt måste även det enklaste programmet i Go vara en del av ett paket. Standardpaketet är main
vanligtvis paketet, det som vi har använt hittills. Om ett program ingår i main
paketet genererar Go en binär fil. När filen körs anropas main()
funktionen.
När du använder main
paketet skapar programmet med andra ord en fristående körbar fil. Men när ett program ingår i ett annat paket än main
genererar Go inte en binär fil. Den genererar en paketarkivfil (en fil som har .a
tillägget).
I Go följer paketnamn en konvention. Ett paket använder den sista delen av importsökvägen som namn. Go-standardbiblioteket innehåller till exempel ett paket med namnet math/cmplx
, som ger användbar kod för att arbeta med komplexa tal. Importsökvägen för det här paketet är math/cmplx
och du importerar det så här:
import "math/cmplx"
Om du vill referera till objekt i paketet använder du paketnamnet, cmplx
, så här:
cmplx.Inf()
Nu ska vi skapa ett paket.
Skapa ett paket
Skapa en ny katalog i katalogen $GOPATH/src
med namnet calculator
. Skapa en fil med namnet sum.go
. Trädkatalogen bör se ut så här:
src/
calculator/
sum.go
sum.go
Initiera filen med namnet på paketet:
package calculator
Nu kan du börja skriva funktionerna och variablerna för paketet. Till skillnad från andra programmeringsspråk anger Go inte nyckelorden public
eller private
för att ange om en variabel eller funktion kan anropas utifrån eller inuti paketet. Men Go följer två enkla regler:
- Om du vill att något ska vara privat startar du namnet med en gemen bokstav.
- Om du vill att något ska vara offentligt startar du namnet med en versal bokstav.
Så vi lägger till följande kod i kalkylatorpaketet som vi skapar:
package calculator
var logMessage = "[LOG]"
// Version of the calculator
var Version = "1.0"
func internalSum(number int) int {
return number - 1
}
// Sum two integer numbers
func Sum(number1, number2 int) int {
return number1 + number2
}
Låt oss titta på några saker i koden:
- Variabeln
logMessage
kan bara anropas inifrån paketet. - Variabeln
Version
kan nås var som helst. Vi rekommenderar att du tar med en kommentar för att beskriva syftet med den här variabeln. (Den här beskrivningen är användbar för alla som använder paketet.) - Funktionen
internalSum
kan bara anropas inifrån paketet. - Funktionen
Sum
kan nås var som helst. Vi rekommenderar att du tar med en kommentar för att beskriva syftet med funktionen.
För att bekräfta att allt fungerar kan du köra go build
kommandot i calculator
katalogen. Om du gör det kan du observera att ingen körbar binär fil genereras.
Skapa en modul
Du har placerat kalkylatorfunktionen i ett paket. Nu är det dags att placera paketet i en modul. Go-moduler innehåller vanligtvis paket som erbjuder relaterade funktioner. Ett pakets modul anger också den kontext som Go behöver för att köra koden som du har grupperat tillsammans. Den här kontextuella informationen innehåller go-versionen som koden är skriven för.
Moduler hjälper även andra utvecklare att referera till specifika versioner av koden och göra det enklare att arbeta med beroenden. En annan fördel är att programmets källkod inte behöver finnas i $GOPATH/src
katalogen. Om du frigör den begränsningen blir det enklare att arbeta med olika paketversioner i andra projekt samtidigt.
Så om du vill skapa en modul för calculator
paketet kör du det här kommandot i rotkatalogen ($GOPATH/src/calculator
):
go mod init github.com/myuser/calculator
När du har kört det här kommandot github.com/myuser/calculator
blir modulens namn. Du använder det namnet för att referera till det i andra program. Kommandot skapar också en ny fil med namnet go.mod
. Slutligen ser trädkatalogen nu ut så här:
src/
calculator/
go.mod
sum.go
Innehållet i go.mod
filen bör se ut som följande kod. (Go-versionen kan vara annorlunda.)
module github.com/myuser/calculator
go 1.14
Om du vill referera till ditt calculator
paket i andra program måste du importera det med hjälp av modulnamnet. I det här fallet är github.com/myuser/calculator
namnet . Nu ska vi titta på ett exempel på hur du använder det här paketet.
Kommentar
Historiskt sett har det inte varit lätt att hantera beroenden i Go. Beroendehanteringssystemet är fortfarande ett pågående arbete. Om du vill lära dig mer om moduler kan du läsa den här serien med inlägg som publicerats i Go-bloggen.
Referera till ett lokalt paket (en modul)
Nu ska vi använda paketet. Vi fortsätter med exempelprogrammet som vi har använt. Den här gången ska vi i stället för att ha sum
funktionen i main
paketet använda den vi skapade tidigare i calculator
paketet.
Trädfilstrukturen bör nu se ut så här:
src/
calculator/
go.mod
sum.go
helloworld/
main.go
Vi använder den här koden för $GOPATH/src/helloworld/main.go
filen:
package main
import (
"fmt"
"github.com/myuser/calculator"
)
func main() {
total := calculator.Sum(3, 5)
fmt.Println(total)
fmt.Println("Version: ", calculator.Version)
}
Observera att import-instruktionen använder namnet på det paket som du skapade: calculator
. Om du vill anropa Sum
funktionen från paketet måste du inkludera paketnamnet, som i calculator.Sum
. Slutligen har du nu också åtkomst till variabeln Version
. Du kallar det så här: calculator.Version
.
Om du försöker köra programmet nu fungerar det inte. Du måste berätta för Go att du använder moduler för att referera till andra paket. Det gör du genom att köra det här kommandot i $GOPATH/src/helloworld
katalogen:
go mod init helloworld
I föregående kommando helloworld
är namnet på projektet. Det här kommandot skapar en ny go.mod
fil, så nu ser trädkatalogen ut så här:
src/
calculator/
go.mod
sum.go
helloworld/
go.mod
main.go
När du öppnar go.mod
filen bör du se något som liknar följande kod. (Go-versionen kan vara annorlunda.)
module helloworld
go 1.14
Eftersom du refererar till en lokal kopia av modulen måste du informera Go om att du inte vill använda en fjärrplats. Så du måste ändra go.mod
filen manuellt så att den innehåller referensen, så här:
module helloworld
go 1.14
require github.com/myuser/calculator v0.0.0
replace github.com/myuser/calculator => ../calculator
Nyckelordet replace
anger att du ska använda en lokal katalog i stället för en fjärrplats för modulen. I det här fallet, eftersom helloworld
programmen och calculator
finns i $GOPATH/src
, är platsen helt enkelt ../calculator
. Om modulens källa finns på en annan plats definierar du den lokala sökvägen här.
Kör programmet med hjälp av det här kommandot:
go run main.go
Utdata ska vara följande:
8
Version: 1.0
Utmaning 1
Vad händer om du försöker anropa variabeln logMessage
eller internalSum
funktionen från calculator
paketet i huvudprogrammet? Körs den? Prova!
Utmaningslösning:
package main import ( "fmt" "github.com/myuser/calculator" ) func main() { total := calculator.internalSum(5) fmt.Println(total) fmt.Println("Version: ", calculator.logMessage) }
Publicera ett paket
Det är ganska enkelt att publicera ett Go-paket . Du behöver bara göra paketets källkod offentligt tillgänglig. De flesta utvecklare använder GitHub för att göra paket tillgängliga för allmänheten, vilket är anledningen till att du ibland hittar referenser till github.com
i importinstruktioner.
Om du till exempel vill publicera paketet calculator
till ditt GitHub-konto måste du skapa en lagringsplats med namnet calculator
. URL:en bör se ut ungefär så här:
https://github.com/myuser/calculator
Du kommer att version dina paket genom att tagga din lagringsplats, så här:
git tag v0.1.0
git push origin v0.1.0
Utvecklare som vill använda ditt paket (inklusive dig) refererar till det så här:
import "github.com/myuser/calculator"
Nu ska vi prata mer detaljerat om hur du refererar till paket från tredje part.
Referera till externa paket (tredje part)
Ibland behöver dina program referera till paket som skrivits av andra utvecklare. Dessa paket är vanligtvis tillgängliga på GitHub. Följande instruktioner för att referera till tredjepartspaket fungerar oavsett om du utvecklar ett paket (ett annat paket än main
) eller ett fristående program (paketet main
).
Nu ska vi lägga till en referens till rsc.io/quote
paketet:
package main
import (
"fmt"
"github.com/myuser/calculator"
"rsc.io/quote"
)
func main() {
total := calculator.Sum(3, 5)
fmt.Println(total)
fmt.Println("Version: ", calculator.Version)
fmt.Println(quote.Hello())
}
Om du använder Visual Studio Code go.mod
uppdateras filen när du sparar filen. Nu ser det ut så här:
module helloworld
go 1.14
require (
github.com/myuser/calculator v0.0.0
rsc.io/quote v1.5.2
)
replace github.com/myuser/calculator => ../calculator
Observera hur rsc.io/quote
refererar till en specifik version av paketet. När du behöver uppgradera programmets beroenden måste du ändra versionen här.
Kör programmet igen med det här kommandot:
go run main.go
Resultatet bör se ut så här:
8
Version: 1.0
Hello, world.
Alla framtida referenser till tredjepartspaket måste finnas i go.mod
filen. När du kör eller kompilerar programmet laddar Go ned alla dess beroenden.