Skip to content

Instantly share code, notes, and snippets.

@joonas-fi joonas-fi/README.md
Last active Feb 8, 2019

Embed
What would you like to do?
Go-koodauksen tipsejä

kirjoitin muutamia ajatuksia ylös Go:n aloittamisesta:

hello worldin ajaminen

yksinkertaisin esimerkki, tallenna samaan hakemistoon nimellä hello.go

package main

import (
  "fmt"
)

func main() {
  fmt.Println("hello world")
}

nyt:

$ go run hello.go
hello world

voidaan myös kääntää se binääriksi

$ go build
$ ./example
hello world

binääristä tulee senniminen kuin mikä sen sisältävä hakemiston nimi on (huomaat tämän myöhemmin hakemistorakenteesta cmd/binäärinnimi/main.go käytännöstä)

otetaan vielä mukaan ulkoinen riippuvuus, muuta hello.go tällaiseksi:

package main

import (
  "fmt"
  "github.com/function61/gokit/mac"
)

func main() {
  fmt.Println(mac.New("secretKey", "message to sign").Sign())
}

nyt haetaan dependenssit (go noutaa github.com/function61/gokit/mac modulin) ja ajetaan ohjelma:

$ go get -d ./...
$ go run hello.go
da3bd8c77b4df8c6

moduulit/importit

  • jos ei ala jollain domain-osoitteella, niin on standardikirjaston moduleita
  • jos alkaa domain-osoitteella (esim. "github.com/function61/gokit"), niin ne on standardikirjaston ulkopuolisia Git repoja
  • go:ssa import-polku on kaikki mitä dependenssien hakemiseen tarvitaan. se on siis sekä dependenssin nimi että tieto mistä dependenssi haetaan. sun tarvitsee vain ajaa $ go get -d ./... niin Go varmistaa että kaikki import-polkujen dependenssit haetaan automaattisesti

private/public: jos funktion, constin, tyypin, globaalin muuttujan tai structin memberin nimi alkaa isolla alkukirjaimella niin se on public, jos pienellä niin se on private. privatet näkyy ainoastaan modulin sisällä ja publicit näkyy modulin ulkopuolelle.

heti kun alat järjestämään oman projektisi koodia useampiin moduleihin (= hakemistoihin), niin sun pitää ymmärtää kuinka gopath toimii: https://golang.org/doc/code.html

käytännössä meinaa että jos et halua kikkailla ENV-muuttujan kanssa, niin sun pitää koodata projektiasi hakemistossa /go/src/github.com/sunnimi/projektinnimi että pystyt importoimaan oman projektisi moduleita. relatiiviset importit toimisivat myös, mutta se ei ole idiomaattista Go:ta.

tähän gopathiin on tulossa muutosta (siitä tulee kai vapaaehtoinen go modulesin myötä), koska tää mekanismi on monien mielestä liian sekava.

idiomaattisista toteutuskäytönnöistä

koodin hakemisto-layout: https://github.com/golang-standards/project-layout

tää on vähän liian pitkälle viety esimerkki, tärkeimmät pointit on:

  • binäärit tulee cmd/binäärinnimi/main.go <-- tästä tulee buildin seurauksena binääri nimelle "binäärinnimi"
  • jos kirjoitat useampia moduleita, niin ne tulee hakemistoon internal/modulinnimi/xyz.go jos modulia ei tarkoiteta että sitä käytetään sun projektin ulkopuolella
  • modulit, jotka tarkoitat että niitä voi importoida muutkin projektit niin tulee vastaavasti hakemistoon pkg/modulinnimi/

mä tosin usein ite pistän kaikki modulit vain pkg/ hakemiston alle, pitäis ehkä internalia käyttää myös rohkeammin. tässä mun esimerkkiprojekti missä olen noudattanut tätä cmd/ ja pkg/ -rakennetta: https://github.com/function61/holepunch-server

tää on aika pelottavan iso dokumentti, mutta siellä on paljon hyviä vinkkejä: https://golang.org/doc/effective_go.html

dependenssien hallinta

go:n työkalut osaa hakea dependenssit $ go get -d ./... komennolla. tämä riittää testiräpellyksiin, mutta ongelmana on se että se hakee master-haaran uusimman, jolloin sun projektis saattaa mennä rikki koska vaan jos joku sun dependenssissä menee rikki tai muuttuu.

tätä ratkaisemaan on tehty uunituore go modules (https://github.com/golang/go/wiki/Modules), mutta itellä on tuotantokäytössä edellinen best practice työkalu go dep (https://github.com/golang/dep), kunnes go modules julistetaan valmiiks tuotantokäyttöä varten

molemmat työkalut rakentuu ton "dependenssit haetaan import-lausekkeiiden perusteella" päälle, mutta ne pinnaa versiot "lukkotiedostoon", jolloin buildit on toistettavia koska dependensseistä haetaan aina samat versiot.

testaus

go:n sisäänrakennettu työkalu on vallan riittävä: $ go test ./... testaa kaikki sun modulit rekursiivisesti (= alihakemistotkin)

docs: https://golang.org/pkg/testing/

esimerkki testauksesta: https://github.com/function61/gokit/blob/master/hashverifyreader/reader_test.go

koodin formatointi

go:n sisäänrakennettu format-työkalu muotoilee go-koodin automaattisesti, jolloin kaikki go-koodi näyttää muotoilun puolesta samalta (hyvä asia), eikä tarvi kiistellä muotoilukäytännöistä koska jokaisella olis kuitenkin oma mielipide

aja vain $ go fmt ./...

kts. lisää: https://golang.org/doc/effective_go.html#formatting

muut työkalut

go:ssa on pirusti järeitä työkaluja sisäänrakennettuna. $ go vet ./... ajaa staattisen analyysin ja löytää paljon virheitä.

löytyy myös sisäänrakennettu benchmarkkaus https://dave.cheney.net/2013/06/30/how-to-write-benchmarks-in-go

race detector https://blog.golang.org/race-detector

go:n työkaluista käytännössä video: https://www.youtube.com/watch?v=uBjoTxosSys (tällä kaverilla on superisti muitakin Go-opetusvideoita)

profilointi suorituskykypullonkaulojen etsimiseen:

staattiseen analyysiin löytyy "meta linter" joka bundlaa sisään monta hyväksihavaittua ulkopuolista lintteriä https://github.com/alecthomas/gometalinter

dokumentaatio

godoc.org on palvelu, joka osaa automaattisesti näyttää minkä tahansa julkisen go-projektin rajapintadokumentaation. tietyllä formaatilla kun liität koodikommentit funktioihin niin ne näkyy silloin tuossa godoc-palvelussakin.

jos haluat katsella dokumentaatiota projektille https://github.com/spf13/cobra, niin vastaava hakusana dokumentaation löytämiseen on "godoc spf13/cobra", jolloin löydät: https://godoc.org/github.com/spf13/cobra

muita resursseja

Go-maailmassa tuut törmäämään asioita Googlatessa Dave Cheneyn ( https://dave.cheney.net/category/golang ) kirjoituksiin, niitä kannattaa lukea koska sillä on paljon hyvää tietoa

https://github.com/avelino/awesome-go (täällä on muun muassa machine learning kategoria)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.