A Go programozási nyelv

Eszközkészlet a nyelvhez

A go parancs

A go parancs célja a Go forráskódok széleskörű igényeket kielégítő kezelése, a fejlesztést segítő eszközök integrálása. A működéséhez egy jól definiált munkakönyvtár struktúra szükséges, a fejlesztőkörnyezet viselkedését környezeti változók révén tudjuk konfigurálni. A legfontosabb környezeti változók az alábbiak:

A Go eszközkészlete széleskörű támogatást nyújt a fejlesztőnek a szoftverfejlesztés folyamatának legfontosabb fázisaihoz, ennek a központi gyűjtőhelye a go parancs, melynek funkciói alparancsok révén érhetőek el:

go parancs [argumentumok]
A következő alparancsok érhetőek el:
build csomagok és függőségeik lefordítása clean a csomagok lefordításából származó tárgzkódok eltávolítása env a működést befolyásoló környezeti változók értékeinek kiíratása fix a fix nevű eszköz futtatása a munkakönyvtárban található csomagokon fmt a csomagok forráskódjainak formázása get csomagok letöltése és telepítése publikus nyíltforrás tárolókból install csomagok fordítása és telepítése munkakönyvtárunk struktúrájába list csomagok listázása run programok fordítása (ha szükséges) és futtatása test csomagok tesztjeinek lefuttatása tool egyéb go eszközök formázása, lásd a go.tools forrástárolót version a Go programcsomag verziójának kiírása vet a vet eszköz futtatása statikus kódelemzéshez

go build - Fordítás

Ez a parancs hívja meg a szükséges Go fordítót, melyet a $GOOS és $GOARCH alapján, vagy ezek hiányában a $GOHOSTOS, $GOHOSTARCH alapján, ha ezek sincsenek beállítva, akkor a futó operációs rendszert és annak platformját veszi alapul. A paraméterként átadott lefordítandó csomagokon túl az import kulcsszavak feldolgozásával felépített függőségi fa csomagjait is, hogyha szükséges őket újrafordítani, a függőségek fa hierarchiája a fordító által biztosított, fordításidejű hibát kapunk, amennyiben a függőségek irányított kört tartalmaznak.
Használata:

go build [-o kimeneti_fájl] [fordítási_kapcsolók] [csomagok/forrásfájlok]

Ha csomagok helyett forrásfájlokat adunk meg, akkor azok a fordító egy csomagba tartozó forrásfájlokként kezeli. A Go programcsomag tartalmaz számos fordító, linkelő, assembler programot a különböző architektúrákhoz egységes elnevezési konvencióval, az első karakter egy számjegy, ami az architektúrát határozza meg, a második pedig a program által ellátott fordítási funkciót, az alábbi kombinációk lehetségesek:

5a Plan 9 assembler ARM architektúrához
5c Plan 9 C fordító ARM architektúrához
5g gc fordító ARM architektúrához
5l linkelő ARM architektúrához
6a Plan 9 assembler x86-64 architektúrához
6c Plan 9 C fordító x86-64 architektúrához
6g gc fordító x86-64 architektúrához
6l linkelő x86-64 architektúrához
8a Plan 9 assembler 32-bites x86 architektúrához
8c Plan 9 C fordító 32-bites x86 architektúrához
8g gc fordító 32-bites x86 architektúrához
8l linkelő 32-bites x86 architektúrához

A go build parancs fordítási opciói

-a a már lefordított és friss csomagok újrafordítása mindenképpen -n a végrehajtandó utasítások kiírás tényleges végrehajtás nélkül -p n a párhuzamosan indítható fordításoknak a száma. Alapértelmezetten az elérhető processzormagok mennyisége. -race versenyhelyzet detektálás engedélyezése a lefordított binárisokban. Csak linux/amd64, darwin/amd64 és windows/amd64 rendszereken támogatott. -v a csomagnevek kiírása azok fordításakor. -work az ideiglenes munkakönyvtár nevének kiírása és annak megtartása a fordítás befejeztével -x a végrehajtott utasítások kiírása -ccflags 'argumentum lista' minden 5c, 6c vagy 8c fordító meghíváskor átadandó argumentumok listája. -compiler name a használandó fordító implementáció megadása (gccgo vagy gc). -gccgoflags 'argumentum lista' minden gccgo fordító/linkelő meghíváskor átadandó argumentumok listája. -gcflags 'argumentum lista' minden 5g, 6g vagy 8g fordító meghíváskor átadandó argumentumok listája. -installsuffix könyvtárvégződés a csomagok telepítési könyvtáránál használandó végződés megadása, annak érdekében, hogy elkülönítsük az alapértelmezett fordításokétól. Ha meg van adva a -race kapcsoló, akkor ennek értéke 'race', illetve, ha adtunk meg explicit végződést, akkor ahhoz a '_race' szöveg fűződik hozzá. -ldflags 'argumentum lista' minden 5l, 6l vagy 8l linkelő meghíváskor átadandó argumentumok listája. -tags 'tag lista' azoknak a tag-eknek a listája, melyeket kielégítettnek tekintünk a fordítás során. A tag-ek a feltételes fordítás eszközei a Go-ban, a forrásfájlokban ezektők függő feltétel kifejezést adhatunk meg, melynek igazra történő kiértékelése esetén a forrásfájl fordításra kerül a megadott csomag részeként. Bővebb leírás a dokumentációban.

go run - Futtatás

Használata:

go run [fordítási_kapcsolók] forrásfájlok... [parancssori_argumentumok]

Lefordítja a megadott forrásfájlokat és futtatja az így kapott binárist, melynek átadja a parancskiadáskor definiált parancssori argumentumokat. Megkötés, hogy a megadott forrásfájloknak ugyanabban a könyvtárban kell lennie és a main csomag részeként kell őket definiálni (package main sor a fájl elejére), viszont csak az egyik tartalmazhat main() függvényt.

go install - Telepítés

go test - Tesztelés és tesztlefedettség

Az eszközkészlet része egy egyszerű tesztelő keretrendszer is, ami a forrásfájljaink mellett elhelyezett tesztfájlok lefordítását, futtatását és kiértékelését végzi el, illetve az automatikus tesztek írásához testing beépített csomag nyújt támogatást a programozó számára. A tesztfájlok szokásos Go nyelven íródott forrásfájlok, ami megkülönbözeti őket az a speciális névkonvenció használata. A tesztfájloknak "_test.go" -ra végződő névvel kell rendelkezniük és a tesztelendő csomagban kell lennie, vagy ha külön csomagba szeretnénk helyezni, akkor forrásfájlban deklaráljuk a "[csomagnév]_test" részeként a tesztkódot. Egy teszt forrásfájlban háromféle függvényt vesz figyelembe a go test:

Tesztfüggvények

A tesztelő függvényeknek az alábbi szignatúrával kell rendelkeznie:

func TestXxx(*testing.T)
Az Xxx helyére tetszőleges alfanumerikus karaktersorozat helyettesíthető.

A tesztfüggvényeink paramétere egy testing.T típusú objektumra mutató pointer, ez az objektum hivított tárolni a tesztelés állapotát, ez az állapot az objektum alábbi metódusaival módosítható:

Egy rövid példa, a testing.Short() a rövidített tesztfuttatás igényét jelzi:

func TestMath(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } result := Add(10,11) if result != 21 { t.Fail() t.Log("The function cannot add 11 to 10.") } if !t.Failed() { result = Pow(result,2) if result != 441 { t.FailNow() } } else { t.FailNow() } t.Log("Test was successful.") }

Egy példa kimenet a tesztfuttatásra, az alábbi rövid eredmény kiíratást a bukott tesztek részletesebb kimenete követi:

ok archive/tar 0.011s FAIL archive/zip 0.022s ok compress/gzip 0.033s ...

Mérések (Benchmark)

A mérések vagy idegennéven benchmark függvényeknek az alábbi szignatúrával kell rendelkeznie:

func BenchmarkXxx(*testing.B)
Az Xxx helyére tetszőleges alfanumerikus karaktersorozat helyettesíthető.

A mérések célja, hogy a tesztelendő csomagunk egy függvényének futási idejét meghatározzuk, itt meg kell jegyezni, hogy ezt az értéket számos dolog befolyásolhatja:

Példák:
func BenchmarkHello(b *testing.B) { for i := 0; i < b.N; i++ { fmt.Sprintf("hello") } } func BenchmarkBigLen(b *testing.B) { big := NewBig() b.ResetTimer() for i := 0; i < b.N; i++ { big.Len() } }

Egy példafuttatás a beépített html/template csomagra:

$ go test -bench ".*" html/template PASS BenchmarkCSSEscaper 500000 5416 ns/op BenchmarkCSSEscaperNoSpecials 2000000 854 ns/op BenchmarkDecodeCSS 1000000 2162 ns/op BenchmarkDecodeCSSNoSpecials 50000000 37.2 ns/op BenchmarkCSSValueFilter 2000000 897 ns/op BenchmarkCSSValueFilterOk 1000000 1173 ns/op BenchmarkEscapedExecute 200000 13468 ns/op BenchmarkHTMLNospaceEscaper 500000 5839 ns/op BenchmarkHTMLNospaceEscaperNoSpecials 2000000 814 ns/op BenchmarkStripTags 500000 4620 ns/op BenchmarkStripTagsNoSpecials 5000000 468 ns/op BenchmarkJSValEscaperWithNum 1000000 1804 ns/op BenchmarkJSValEscaperWithStr 200000 8683 ns/op BenchmarkJSValEscaperWithStrNoSpecials 1000000 2240 ns/op BenchmarkJSValEscaperWithObj 200000 10005 ns/op BenchmarkJSValEscaperWithObjNoSpecials 500000 3330 ns/op BenchmarkJSStrEscaperNoSpecials 2000000 813 ns/op BenchmarkJSStrEscaper 500000 5133 ns/op BenchmarkJSRegexpEscaperNoSpecials 5000000 714 ns/op BenchmarkJSRegexpEscaper 500000 5198 ns/op BenchmarkURLEscaper 500000 6600 ns/op BenchmarkURLEscaperNoSpecials 5000000 602 ns/op BenchmarkURLNormalizer 500000 4994 ns/op BenchmarkURLNormalizerNoSpecials 5000000 728 ns/op ok html/template 62.427s

Példaprogramok helyessége

A példaprogramokat tartalmazó függvényeknek az alábbi szignatúrával kell rendelkeznie:

func ExampleXxx()
Az Xxx helyére tetszőleges alfanumerikus karaktersorozat helyettesíthető.

A példaprogramok speciális tesztesetekként működnek a Go-ban, itt nincs szükség, sem lehetőség a tesztfutás állapotának módosítására, az automatikusan történik. A teszt specifikusan a standard output-ra küldött kimeneteket ellenőrzi, erre a feltételt egy "Output:" kezdetű komment formájában kell megfogalmaznunk a függvénytörzsben, az ellenőrzésnél a soreleji és sorvégi whitespace-eket nem veszi figyelembe. Ezek a függvények a kimenet ellenőrzésén túl dokumentációs jelentőséggel is bírnak, a godoc által generált dokumentációba is bekerülnek, így biztosítható, hogy helyesen működő programok szerepeljenek a csomagjaink dokumentációjában.

func ExampleHello() { fmt.Println("hello") // Output: hello } func ExampleSalutations() { fmt.Println("hello, and") fmt.Println("goodbye") // Output: // hello, and // goodbye }

go clean - Takarítás

A go clean parancs a forráskönyvtárakban található tárgykódok eltávolítására szolgál. Alapesetben a go parancs egy ideiglenes könyvtárban helyezi el a fordítás közben létrejövő tárgykódokat, ezért ezt a parancsot főként egyéb eszközök vagy manuális go build futtatások által hátrahagyott fájlok eltakarításához használják.

Kapcsolók:

-i Eltávolítja a 'go install' parancs által telepített fájlokat is. -n Kiírja a végrehajtandó parancsokat, de nem végzi őket el. -r Rekurzív tisztítást végez a forrásokból kiolvasható csomagfüggőségek mentén. -x Kiírja a végrehajtandó parancsokat és el is végzi őket el.

go get - Forráskód letöltés és telepítés

Letölti és telepíti a megadott elérési utak által meghatározott csomagokat és azok függőségeit, az elérési utak formátuma a forrásokban használt import kifejezésekben találhatóakkal megegyező kell, hogy megegyezzen. A Go támogat számos online forráskódtároló oldalt, melyekről a kódokat a nekik megfelelő verziókövető rendszerek segítségével szerzi meg:

Bitbucket (Git, Mercurial) import "bitbucket.org/user/project" import "bitbucket.org/user/project/sub/directory" GitHub (Git) import "github.com/user/project" import "github.com/user/project/sub/directory" Google Code Project Hosting (Git, Mercurial, Subversion) import "code.google.com/p/project" import "code.google.com/p/project/sub/directory" import "code.google.com/p/project.subrepository" import "code.google.com/p/project.subrepository/sub/directory" Launchpad (Bazaar) import "launchpad.net/project" import "launchpad.net/project/series" import "launchpad.net/project/series/sub/directory" import "launchpad.net/~user/project/branch" import "launchpad.net/~user/project/branch/sub/directory"

Kapcsolók:

-d Csak a letöltést végzi el, telepítést nem. -fix A 'go fix' futtatása a forrásokon mielőtt azokat telepítené. -t A csomagokhoz tartozó tesztkódok lefordítása. -u Ha létezik már lokálisan a csomag akkor is letölti a legfrissebb változatot és azok függőségeit.

go fix / go tool fix - Forráskód javítás

A verziók közötti API változások automatikus követésére, a források automatikus frissítésére használható ez az eszköz. Az 1.2-es verzióval elkülönült az eszköz egy másik forrástárolóba, így a használata is megváltozott go tool fix-re, a régi forma is jelen van még az egyszerűbb használat és a kompatibilitás miatt, de részletesebb beállítások nem használhatóak vele.

go fmt - Forráskód formázás

Automatikus forráskód formázó eszköz, a paraméterként megadott csomagokban található forrásokat alakítja át. Ez eszköz segítséget ad az IDE-k kódformázó eszközeinek megvalósításához.

go vet - Statikus kódelemzés

A forráskódok statikus elemzésével keres gyanús konstrukciókat a programokban. Nem minden találat jelent potenciális hibát, de segíthet a fordító által nem észlelt hibák feltárásában a beépített heurisztikák segítségével. Meghívható csomagokra, fájlokra vagy könyvtárakra. Az elvégezhető ellenőrzések részletesen a godoc code.google.com/p/go.tools/cmd/vet parancs használatával tekinthetőek meg.

godoc - Dokumentáció generálás

Tetszőleges csomagból a Go dokumentációs komment konvenciója alapján dokumentációt generál. Alapesetben a generált dokumentációt karakteres formában a standard output-ra írja az eszköz. A másik üzemmódja az eszköznek -http kapcsoló használatával történik, ilyenkor a godoc -http=<hosztnév>:<port> parancs kiadásával saját webszerver indítható, mely a honlappal megegyező formátumú honlapot szolgáltat és a "Packages" menüpont alatt a $GOROOT és $GOPATH változók szerinti forráskönyvtárak csomagjainak dokumentációja jelenik meg. A dokumentáció részei a csomagokban speciálisan elnevezett példaprogramok is (lásd: Példaprogramok helyessége), melyek ilyenkor lefordításra és helyességellenőrzésre kerülnek, majd beépülnek a dokumentációba.

Dokumentálási konvenció

A Godoc megközelítése rokon a Python-os Docstring és a Java-s Javadoc-kal, viszont egyszerűbbre tervezték náluk. Godoc esetén a dokumentációs kommentek nem nyelvi elemek, mint Python esetén és nem kell olyan szintaktikai szabályokat sem követniük, mint a Javadoc esetén kell. A tervezők szerint ezek egyszerűen olyan jó kommenteknek kell, hogy legyenek, amiket a Godoc létezése nélkül is olvasni szeretnél a kódban.

A konvenció röviden: a dokumentálandó típus, csomagszintű változó/konstans, függvény, vagy épp maga a csomag elé írj egy hagyományos kommentet üres sor közbeékelése nélkül és a dokumentáció a program hierarchiájának megfelelően fog elkészülni. Példaként az fmt csomag Fprint függvényét megelőző sorok:

// Fprint formats using the default formats for its operands and writes to w. // Spaces are added between operands when neither is a string. // It returns the number of bytes written and any write error encountered. func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
A csomagok dokumentálása esetén néha bőbeszédűbb bevezetést kell írnia fejlesztőknek a csomagról, ilyenkor nem célszerű ezt egy kiválasztott csomagbeli forrásfájl elején megtenni ezt, mert az nehezebben olvashatóvá teheti a kódot, ezért ilyenkor a konvenció szerint ennek hozzunk létra a csomagban egy külön forrásfájlt doc.go néven, melynek tartalma csak a dokumentációt tartalmazó komment és azt követően package <csomagnév> sor.

A kommentek tartalmához néhány esetben különleges jelentés vagy formázás társul: