Go dla początkujących - Część 5: Pakiety i importy
Mateusz Kędziora

Witaj w kolejnym wpisie z serii o języku Go! Dzisiaj zajmiemy się tematem, który jest fundamentem każdego większego projektu – pakiety i importy. Bez tego mechanizmu tworzenie rozbudowanych programów byłoby chaotyczne i trudne. Pakiety pozwalają nam na modularne dzielenie kodu, a importy umożliwiają korzystanie z kodu napisanego przez innych. Zaczynamy!
Co to są pakiety i dlaczego są ważne?
Wyobraź sobie, że budujesz dom. Nie wrzucasz wszystkich cegieł, desek i gwoździ w jedną wielką kupę, prawda? Zamiast tego, sortujesz materiały według ich przeznaczenia – cegły na ściany, drewno na dach, itp. Podobnie jest z kodem. Pakiet (package) to sposób na logiczne grupowanie powiązanych funkcji, zmiennych i typów. To jakbyś miał oddzielne “pokoje” w swoim projekcie, każdy z własnym zestawem narzędzi.
Dzięki pakietom:
- Kod jest bardziej zorganizowany: Łatwiej odnaleźć potrzebne elementy i unikać chaosu.
- Można ponownie wykorzystywać kod: Pakiety z dobrze napisanym kodem możesz wykorzystać w różnych miejscach projektu, a nawet w innych projektach.
- Praca zespołowa staje się łatwiejsza: Różne osoby mogą pracować nad różnymi pakietami bez wchodzenia sobie w drogę.
- Kod jest bardziej czytelny: Łatwiej zrozumieć, co robi dany fragment kodu, kiedy jest uporządkowany.
W Go, każdy plik .go musi należeć do jakiegoś pakietu. Deklaruje się to na początku pliku, za pomocą słowa kluczowego package
.
Importy: Korzystanie z kodu innych
Kiedy już podzielimy nasz kod na pakiety, potrzebujemy sposobu, żeby z tych pakietów korzystać. Tutaj z pomocą przychodzą importy. Importy pozwalają na używanie kodu z innych pakietów w naszym aktualnym kodzie. To tak jakbyśmy mogli w naszym domu skorzystać z narzędzi z sąsiedniego domu – oczywiście za ich zgodą (w tym przypadku zgoda jest implicitowana poprzez eksport).
Go ma wiele wbudowanych pakietów w tzw. bibliotece standardowej. Dostępnych jest również wiele pakietów zewnętrznych, które udostępniają funkcjonalności rozszerzające możliwości języka.
Biblioteka Standardowa Go: Skarbnica gotowych rozwiązań
Biblioteka standardowa Go to zestaw pakietów, które są dołączone do każdej instalacji języka. Znajdziesz w niej pakiety do obsługi plików, sieci, operacji matematycznych, tekstu i wielu innych zadań.
Przykłady popularnych pakietów:
fmt
: Służy do formatowania wejścia/wyjścia, np. drukowania na ekranie.math
: Zawiera funkcje matematyczne, np. obliczanie pierwiastka kwadratowego.net/http
: Pozwala na tworzenie serwerów i klientów HTTP.os
: Umożliwia interakcję z systemem operacyjnym, np. odczytywanie zmiennych środowiskowych.strings
: Zawiera funkcje do manipulacji łańcuchami znaków.
Aby skorzystać z pakietu, musimy go zaimportować na początku pliku za pomocą słowa kluczowego import
. Oto przykład importowania pakietu fmt
:
package main
import "fmt"
func main() {
fmt.Println("Witaj, świecie!")
}
W tym przykładzie importujemy pakiet fmt
, a następnie używamy funkcji Println
z tego pakietu do wyświetlenia tekstu.
Możemy zaimportować wiele pakietów w jednej deklaracji importu, grupując je w nawiasach:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Pierwiastek z 16 to:", math.Sqrt(16))
}
Importowanie pakietów z zewnątrz
Oprócz pakietów standardowych, możesz korzystać z pakietów dostępnych w Internecie. Najpopularniejszym źródłem jest Go Modules, które pozwalają na zarządzanie zależnościami projektu.
Aby zaimportować pakiet zewnętrzny, musisz znać jego ścieżkę. Na przykład, popularnym pakietem do obsługi JSON jest encoding/json
. Importuje się go tak samo jak pakiet standardowy:
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
data := []byte(`{"name": "Jan", "age": 30}`)
var person Person
err := json.Unmarshal(data, &person)
if err != nil {
fmt.Println("Błąd podczas dekodowania JSON:", err)
return
}
fmt.Printf("Imię: %s, Wiek: %d\n", person.Name, person.Age)
}
W tym przykładzie importujemy pakiet encoding/json
, tworzymy strukturę Person
i za pomocą funkcji Unmarshal
dekodujemy dane w formacie JSON. Po wpisaniu tego kodu możesz go uruchomić, jeśli masz odpowiednio skonfigurowane środowisko dla modułów. Jeśli nie posiadasz jeszcze modułu, możesz go zainicjalizować poleceniem: go mod init example/my-app
, a następnie wpisać ten kod w plik main.go
. Uruchomić kod możesz poleceniem go run .
Aby używać pakietów zewnętrznych w swoich projektach, musisz je najpierw zainstalować. Go Modules ułatwiają ten proces. Go samodzielnie będzie śledzić i pobierać potrzebne pakiety.
Widoczność identyfikatorów: Co jest publiczne, a co prywatne?
W Go, widoczność identyfikatorów (np. zmiennych, funkcji, typów) jest kontrolowana przez ich nazwę. Ta zasada jest bardzo prosta:
- Eksportowane (publiczne) identyfikatory: Zaczynają się z wielkiej litery. Oznacza to, że są dostępne z innych pakietów.
- Nieeksportowane (prywatne) identyfikatory: Zaczynają się z małej litery. Są dostępne tylko wewnątrz pakietu, w którym zostały zdefiniowane.
To proste podejście jest bardzo skuteczne i promuje pisanie bardziej zorganizowanego i zrozumiałego kodu.
Przykład:
// package mypackage
package mypackage
// Eksportowana funkcja
func Add(a, b int) int {
return a + b
}
// Nieeksportowana funkcja
func subtract(a, b int) int {
return a - b
}
// Eksportowana zmienna
var Counter int
// Nieeksportowana zmienna
var internalCounter int
W tym przykładzie, funkcja Add
i zmienna Counter
są eksportowane i mogą być używane z innych pakietów. Funkcja subtract
i zmienna internalCounter
są prywatne i mogą być używane tylko w pakiecie mypackage
.
Przykład użycia:
package main
import (
"fmt"
"example/mypackage"
)
func main() {
result := mypackage.Add(5, 3)
fmt.Println("Wynik dodawania:", result) // Wyświetli: Wynik dodawania: 8
mypackage.Counter = 10
fmt.Println("Licznik:", mypackage.Counter) // Wyświetli: Licznik: 10
// Poniższa linijka spowoduje błąd, ponieważ nie możemy się odwołać do nieeksportowanej funkcji
// mypackage.subtract(10,5)
// Podobnie nie możemy zmienić wewnętrznej zmiennej pakietu
// mypackage.internalCounter = 10
}
Tworzenie własnych pakietów
Teraz, gdy wiemy, jak importować pakiety, czas nauczyć się tworzyć własne. To bardzo proste:
- Utwórz katalog dla swojego pakietu: Wybierz nazwę dla swojego pakietu i utwórz katalog o tej samej nazwie. Na przykład, utwórz katalog
mypackage
. - Utwórz plik .go w tym katalogu: Wewnątrz katalogu utwórz plik z rozszerzeniem
.go
. Na przykład,mypackage.go
. - Zadeklaruj pakiet na początku pliku: Na początku pliku użyj słowa kluczowego
package
, podając nazwę katalogu, który będzie nazwą pakietu. Na przykład:package mypackage
. - Dodaj kod: Teraz możesz dodawać zmienne, funkcje, typy i wszystko, czego potrzebujesz. Pamiętaj, aby eksportować elementy, które chcesz udostępnić innym.
Przykład struktury katalogów:
myproject/
main.go
mypackage/
mypackage.go
Zawartość mypackage.go
:
package mypackage
// Funkcja do pozdrawiania
func Greet(name string) string {
return "Witaj, " + name + "!"
}
// Funkcja licząca długość stringa
func Length(text string) int {
return len(text)
}
// Prywatna zmienna
var secret string = "Shhh!"
// Publiczna zmienna
var Message string = "This is public!"
Zawartość main.go
:
package main
import (
"fmt"
"example/myproject/mypackage"
)
func main() {
greeting := mypackage.Greet("Go developer")
fmt.Println(greeting) // Output: Witaj, Go developer!
length := mypackage.Length("Hello")
fmt.Println("Długość stringa:", length) // Output: Długość stringa: 5
fmt.Println("Publiczny komunikat: ", mypackage.Message) // Output: Publiczny komunikat: This is public!
// Poniższa linijka zwróci błąd:
// fmt.Println(mypackage.secret)
}
Ważne: W tym przykładzie, musisz uruchomić program będąc w katalogu myproject
, tak żeby moduły mogły poprawnie zaimportować twój pakiet. Do uruchomienia kodu użyj komendy: go run .
Jasne, oto artykuł na bloga o instalacji pakietów w projekcie Go:
Go Modules
Od wersji Go 1.11, Go używa Go Modules do zarządzania zależnościami projektu. Go Modules to system, który pozwala nam określić, jakie pakiety są potrzebne do naszego projektu i w jakich wersjach. Dzięki temu, możemy łatwo udostępniać nasze projekty i mieć pewność, że inni będą mogli je uruchomić bez problemów.
Inicjalizacja modułu
Aby rozpocząć korzystanie z Go Modules, musimy najpierw zainicjalizować moduł w naszym projekcie. Robimy to za pomocą komendy go mod init
. Na przykład, jeśli chcemy utworzyć moduł o nazwie github.com/user/repo
, możemy to zrobić tak:
go mod init github.com/user/repo
Ta komenda utworzy plik go.mod
w katalogu głównym naszego projektu. Plik ten będzie zawierał informacje o naszym module, takie jak jego nazwa i wersja Go, której używamy.
Dodawanie pakietów
Aby dodać pakiet do naszego projektu, możemy użyć komendy go get
. Na przykład, jeśli chcemy dodać pakiet github.com/gorilla/mux
, możemy to zrobić tak:
go get github.com/gorilla/mux
Ta komenda pobierze pakiet github.com/gorilla/mux
i jego zależności, a następnie doda go do pliku go.mod
.
Aktualizacja pakietów
Aby zaktualizować pakiet do najnowszej wersji, możemy użyć komendy go get -u
. Na przykład, jeśli chcemy zaktualizować pakiet github.com/gorilla/mux
, możemy to zrobić tak:
go get -u github.com/gorilla/mux
Ta komenda pobierze najnowszą wersję pakietu github.com/gorilla/mux
i jego zależności, a następnie zaktualizuje plik go.mod
.
Usuwanie pakietów
Aby usunąć pakiet z naszego projektu, możemy użyć komendy go mod tidy
. Ta komenda usunie z pliku go.mod
wszystkie pakiety, które nie są już używane w naszym projekcie.
Przykłady
Oto kilka przykładów użycia pakietów w projekcie Go:
package main
import (
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func main() {
r := mux.NewRouter()
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, world!")
})
http.ListenAndServe(":8080", r)
}
W tym przykładzie, używamy pakietu github.com/gorilla/mux
do utworzenia routera HTTP. Router HTTP to komponent, który pozwala nam mapować adresy URL na funkcje, które będą obsługiwać te adresy.
package main
import (
"fmt"
"time"
"github.com/robfig/cron"
)
func main() {
c := cron.New()
c.AddFunc("0 0 * * *", func() {
fmt.Println("Hello, world!")
})
c.Start()
time.Sleep(time.Hour)
}
W tym przykładzie, używamy pakietu github.com/robfig/cron
do utworzenia cron joba. Cron job to zadanie, które jest wykonywane regularnie, zgodnie z harmonogramem. W tym przypadku, cron job będzie wyświetlał komunikat “Hello, world!” co godzinę.
Podsumowanie
Pakiety i importy to podstawowe mechanizmy w Go, które pozwalają na pisanie zorganizowanego i efektywnego kodu. Dzięki nim możemy dzielić kod na logiczne moduły, wykorzystywać bibliotekę standardową oraz korzystać z gotowych rozwiązań udostępnianych przez społeczność.
- Pakiety: Służą do grupowania kodu. Każdy plik .go musi należeć do pakietu.
- Importy: Pozwalają na korzystanie z kodu z innych pakietów.
- Biblioteka standardowa: Zawiera gotowe pakiety do różnych zadań.
- Widoczność identyfikatorów: Kontrolowana przez wielkość pierwszej litery (eksportowane lub nieeksportowane).
- Tworzenie własnych pakietów: Prosty proces polegający na utworzeniu katalogu, pliku i zadeklarowaniu pakietu.
Praca Domowa
- Utwórz własny pakiet o nazwie
mymath
, który będzie zawierał dwie funkcje:Add(a, b int) int
- zwraca sumę dwóch liczb całkowitych.Multiply(a, b int) int
- zwraca iloczyn dwóch liczb całkowitych.
- W pliku
main.go
zaimportuj pakietmymath
i użyj tych funkcji. Wyświetl wyniki. - Utwórz zmienną w pakiecie
mymath
, która nie będzie eksportowana. Zobacz czy jesteś w stanie się do niej odwołać w plikumain.go
. - Poszukaj ciekawego pakietu zewnętrznego i spróbuj go zaimportować i użyć w swoim projekcie.
Zachęcam do eksperymentowania! Im więcej będziesz ćwiczyć, tym szybciej opanujesz te koncepcje. Nie zapomnij także zajrzeć do innych wpisów z serii, aby poznać jeszcze więcej tajników języka Go. Powodzenia!
Polecane artykuły
Docker vs Kubernetes: Który dla Ciebie w 2025?
Docker i Kubernetes objaśnione! Która technologia lepsza dla początkujących w 2025? Porównanie, przykłady i przyszłość.
Mateusz Kędziora
DevOps: Automatyzacja zadań sysadmina dla programistów
Zautomatyzuj pracę sysadmina w środowisku DevOps! Praktyczne przykłady, skrypty, Ansible, Terraform, Prometheus i Grafana.
Mateusz Kędziora
Automatyzacja Linux/macOS z Bash: Praktyczny Przewodnik
Zacznij automatyzować system Linux/macOS z Bash! Dowiedz się, czym jest Bash, jak pisać skrypty i używać podstawowych komend.
Mateusz Kędziora