Zapraszam na kolejny odcinek kursu Go. W tej części zajmiemy się pakietami. Krótko mówiąc, pakiety odpowiadają za katalogowanie i logiczny podział funkcjonalności na oddzielne „worki”. Umieszczanie wszystkich plików w jednym folderze wprowadza niepotrzebny bałagan. Właśnie ten problem rozwiązują pakiety.
Z pierwszym pakietem mieliśmy już do czynienia. Jest to pakiet main
, który pełni specjalną funkcję. Odpowiada on za miejsce, w którym może rozpoczynać się wykonywanie naszego kodu. Do pełni szczęścia będziemy potrzebować tylko funkcji main()
.
package main func main() { // execution starts here }
Jeśli funkcja main()
znajdzie się w innym pakiecie main, to będzie się zachowywać jak każda inna funkcja. W folderze może znajdować się maksymalnie jeden pakiet (to nie do końca prawda, lecz o testach opowiem później). Owe pakiety fizycznie są umieszczane w osobnych folderach. To coś na wzór pakietów w Javie. Mogłem trochę namieszać, więc wyjaśnię na przykładzie.
➜ ls -la drwxr-xr-x 6 bkielbasa staff 192 Aug 30 19:55 . drwxr-xr-x 3 bkielbasa staff 96 Aug 30 19:51 .. -rw------- 1 bkielbasa staff 18 Aug 30 19:52 go.mod -rw-r--r-- 1 bkielbasa staff 60 Aug 30 19:52 main.go drwxr-xr-x 2 bkielbasa staff 64 Aug 30 19:55 pkg1 drwxr-xr-x 2 bkielbasa staff 64 Aug 30 19:55 pkg2
W powyższym zestawieniu mamy plik main.go
, będący miejscem, od którego zaczyna się wykonywanie aplikacji. Są też foldery pkg1
oraz pkg2
. Nazwy podfolderów powinny pasować do nazw pakietów, które znajdują się wewnątrz. Jest od tego jeden wyjątek, mianowicie pakiet main. Tak, można mieć wiele pakietów main w obrębie jednego projektu, a każdy będzie uruchamiać inną wersję aplikacji.
Go modules
Od wersji Go 1.11 mamy wbudowany system zarządzania pakietami. W końcu! Aby móc zacząć z niego korzystać, należy wpisać komendę go mod init github.com/some/pkg
w katalogu głównym projektu.
Dobrą praktyką jest nazywanie pakietu od adresu repozytorium. Pozwala to zachować spójność oraz umożliwia tworzenie unikatowych nazw pakietów.
Tym sposobem otrzymujemy nowy plik o nazwie go mod
, w którym będą znajdować się informacje o naszych zależnościach. Gdy wykonamy polecenia takie jak go test/build/run
i tym podobne, Go automatycznie pobierze wszystkie te zależności za nas. W wyżej wymienionym pliku znajdować się mogą też dwie inne informacje.
module github.com/some/pkg go 1.13 require ( github.com/stretchr/testify v1.4.0 )
Pierwsza to nazwa naszego modułu, a kolejna to wersja języka Go, który jest wymagany przez bibliotekę/aplikację. Jak pobrać zależność? Przede wszystkim należy zacząć jej używać. Golang jest w tej kwestii dość restrykcyjny i nie pozwala na kompilację, gdy w kodzie jest nieużyty import.
Import jest to słowo kluczowe, które daje nam możliwość użycia jakiegoś pakietu w naszym pliku. Nie ma znaczenia, czy ten pakiet znajduje się w projekcie, czy też jest zewnętrzną zależnością.
package yours import ( "testing" "github.com/stretchr/testify/assert" ) func TestSomething(t *testing.T) { assert.True(t, true, "True is true!") }
Następnie wpisujemy komendę go get github.com/nazwa/pakietu
i czekamy kilka chwil. Środowisko takie jak GoLand (od JetBrains) potrafi tę operację wykonać z poziomu edytora. Wystarczy wcisnąć alt+enter. Od tego momentu możemy korzystać z zewnętrznej zależności bez problemów.
To, co warto podkreślić, to fakt, że tę nazwę, którą podamy w pliku go.mod
, użytkownicy naszej biblioteki będą musieli podać u siebie. To znaczy, że jeśli nasz moduł nazywa się module github.com/some/pkg
, to pobieranie tej zależności będzie wyglądać następująco:
go get github.com/some/pkg
Wróćmy jeszcze do dostępności funkcji oraz struktur. Warto pamiętać, że ta sama zasada będzie się tyczyła również zewnętrznych zależności – nie można użyć funkcji/struktur/stałych, które nie są wyeksportowane (zapisane wielką literą).
Istnieje też specjalny i dość specyficzny rodzaj pakietu – internal.
Jeśli coś jest dla Ciebie niezrozumiałe, to śmiało pytaj w komentarzach. Chętnie zaktualizuję wpis. :) Zachęcam również do dodawania propozycji zagadnień, które mógłbym poruszyć. Powoli kończą się tematy podstawowe, a chcę dostosowywać treści do Twoich potrzeb.
“Tym sposobem otrzymujemy nowy plik o nazwie go mod” brakuje kropki pomiędzy “go” a “mod”.