Kaikki mitä sinun tarvitsee tietää paketeista Go:ssa

Pakettien alustaminen

Kun ajamme Go:n ohjelmaa, Go-kääntäjä noudattaa tiettyä suoritusjärjestystä paketeille, paketin sisältämille tiedostoille ja näissä tiedostoissa oleville muuttujien selityksille.

Pakettien laajuus

Laajuusalue (scope, scope) eli laajuusalue (scope) on koodilohkossa oleva alue, jossa määriteltyyn muuttujaan pääsee. Paketin laajuus on alue paketissa, jossa määriteltyyn muuttujaan pääsee käsiksi paketin sisältä (kaikista paketin tiedostoista). Tämä alue on paketin minkä tahansa tiedoston ylimpänä oleva lohko.

Katso go run-komentoa. Tällä kertaa yhden tiedoston suorittamisen sijaan meillä on glob-kuvio, joka sisällyttää kaikki tiedostot app-paketin sisällä suoritettavaksi.

Go on tarpeeksi fiksu tajutakseen sovelluksen tulopisteen, joka on entry.go, koska sillä on main-funktio. Voimme myös käyttää alla olevan kaltaista komentoa (tiedostojen järjestyksellä ei ole väliä).

go run src/app/version.go src/app/entry.go

💡 Voit myös käyttää go run app-komentoa, joka tekee saman asian, ja tämä on parempi lähestymistapa paketin suorittamiseen. go install– tai go build-komento vaatii paketin nimen, joka sisältää kaikki paketin sisällä olevat tiedostot, joten meidän ei tarvitse määritellä niitä kuten edellä.

Palatakseni pääkysymykseemme, voimme käyttää muuttujaa version, joka on julistettu version.go-tiedostossa, mistä tahansa paketissa, vaikka sitä ei ole viety (kuten Version), koska se on julistettu paketin laajuudessa.

Jos muuttuja version olisi julistettu funktion sisällä, se ei olisi ollut paketin laajuudessa ja yllä oleva ohjelma olisi epäonnistunut kääntämisessä.

Sinä et saa julistaa uudelleen samannimistä globaalia muuttujaa samassa paketissa. Näin ollen, kun version muuttuja on kerran ilmoitettu, sitä ei voi ilmoittaa uudelleen paketin laajuudessa. Mutta muualla sen voi vapaasti julistaa uudelleen.

Muuttujien alustaminen

Kun muuttuja a on riippuvainen toisesta muuttujasta b, b tulee b määritellä etukäteen, muutoin ohjelma ei käänny. Go noudattaa tätä sääntöä funktioiden sisällä.

Mutta kun nämä muuttujat määritellään pakettien (package scope) sisällä, ne ilmoitetaan aloitusjaksoissa. Katsotaanpa alla olevaa yksinkertaista esimerkkiä.

Ylläolevassa esimerkissä ensin julistetaan c, koska sen arvo on jo ilmoitettu. Myöhemmässä alustussyklissä b julistetaan, koska se riippuu c:stä ja c:n arvo on jo julistettu. Viimeisessä alustussyklissä a julistetaan ja annetaan b:n arvoksi. Go pystyy käsittelemään monimutkaisia alustussyklejä kuten alla.

Yllä olevassa esimerkissä ensin julistetaan c ja sen jälkeen b, koska sen arvo on riippuvainen c:stä, ja lopuksi a, koska sen arvo on riippuvainen b:sta. Kannattaa välttää alla olevan kaltaisia alustussilmukoita, joissa alustaminen menee rekursiiviseksi silmukaksi.

Toinen esimerkki pakettien soveltamisalasta olisi, että erillisessä tiedostossa olisi funktio f, joka viittaa muuttujaan c päätiedostosta.

Init-funktio

Kuten main funktio, init funktiota Go kutsuu, kun paketti alustetaan. Se ei ota argumentteja eikä palauta mitään arvoa.

Funktio init on Go:n implisiittisesti julistama, joten siihen ei voi viitata mistään (tai kutsua sitä kuten init()). Tiedostossa tai paketissa voi olla useita init-funktioita. Tiedostossa olevien init-funktioiden suoritusjärjestys on niiden esiintymisjärjestyksen mukainen.

Sinulla voi olla init-funktio missä tahansa pakkauksessa. init-funktion tärkein tehtävä on siis alustaa globaalit muuttujat, joita ei voida alustaa globaalissa kontekstissa. Esimerkiksi joukon alustaminen.

Koska for-syntaksi ei kelpaa paketin laajuudessa, voimme alustaa joukon integers, jonka koko on 10, for-silmukan init-funktion sisällä.

Paketin alias

Kun tuot paketin, Go luo muuttujan käyttäen paketin paketti-ilmoitusta. Jos tuot useita samannimisiä paketteja, tämä johtaa ristiriitaan.

// greet/parent.go
package greetvar Message = "Hey there. I am parent."// greet/greet/child.go
package greetvar Message = "Hey there. I am child."

Käytämme siis pakettialiasia. Ilmoitamme import-avainsanan ja paketin nimen väliin muuttujan nimen, josta tulee uusi muuttuja, jolla viitataan pakettiin.

Yllä olevaan esimerkkiin, greet/greet-pakettiin viitataan nyt muuttujan child avulla. Jos huomaat, aliasimme greet-paketin alleviivauksella.

Alleviivaus on Go:ssa erikoismerkki, joka toimii null-säiliönä. Koska tuomme greet-paketin mutta emme käytä sitä, Go-kääntäjä valittaa siitä. Välttääksemme sen, tallennamme kyseisen paketin viittauksen _:iin ja Go-kääntäjä yksinkertaisesti jättää sen huomiotta.

Paketin liittäminen alleviivauksella, joka ei näytä tekevän mitään, on joskus varsin hyödyllistä, kun halutaan alustaa paketti, mutta ei käyttää sitä.

// greet/parent.go
package greetimport "fmt"var Message = "Hey there. I am parent."func init() {
fmt.Println("greet/parent.go ==> init()")
}// greet/greet/child.go
package greetimport "fmt"var Message = "Hey there. I am child."func init() {
fmt.Println("greet/greet/child.go ==> init()")
}

Tärkeintä on muistaa, että tuotu paketti initialisoidaan vain kerran per paketti. Jos siis paketissa on useita import-lausekkeita, tuotu paketti alustetaan vain kerran pääpaketin suorituksen aikana.