Lär dig mer om paket

Slutförd

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 maingenererar 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/cmplxoch 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/calculatornamnet . 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.