archive tar zip bufio builtin bytes compress bzip2 flate gzip lzw
zlib container heap list ring crypto aes cipher des dsa ecdsa
elliptic hmac md5 rand rc4 rsa sha1 sha256 sha512 subtle tls
x509 pkix database sql driver debug dwarf elf gosym macho pe
encoding ascii85 asn1 base32 base64 binary csv gob hex json
pem xml errors expvar flag fmt go ast build doc format parser
printer scanner token hash adler32 crc32 crc64 fnv html
template image color draw gif jpeg png index suffixarray io
ioutil log syslog math big cmplx rand mime multipart net http
cgi cookiejar fcgi httptest httputil pprof mail rpc jsonrpc smtp
textproto url os exec signal user path filepath reflect regexp
syntax runtime cgo debug pprof race sort strconv strings sync
atomic syscall testing iotest quick text scanner tabwriter
template parse time unicode utf16 utf8 unsafe
package workq type Queue []*Item func (q *Queue) Push(item *Item) { *q = append(*q, item) go item.Translate() } func (q *Queue) Pop() *Item { if !q.IsEmpty() { old := *q item := old[0] <- item.Done *q = old[1:len(old)] return item } return nil } func (q *Queue) Len() int { return len(*q) }
* Linux, FreeBSD
Инсталирате си пакета go
от вашия пакетен мениджър
* Mac OSX
Използвате симпатичния инсталатор
* Windows
1. Създавате директория ~/go
2. Слагате следните два реда в ~/.profile
export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin
* За Windows-аджийте има уловки:
C:\Go
вместо вас и можете да ползвате неяЗа да сме сигурни, че сме направили всичко като хората, създаваме файл hello.go:
package main import "fmt" func main() { fmt.Printf("Hello, world!\n") }
и изпълняваме
go run hello.go
Ако всичко изглежда наред, правим скрийншот и получаваме точка :)
Имаме инструментът go
, който се грижи за достатъчно много неща.
Повечето настройки се правят с environment variables
.
workspace
, с три основни директории:
src
съдържа нашия сорс код, който е организиран в пакети (за тях след малко)pkg
съдържа т.нар. package objects
bin
съдържа компилираните ни програмиbuild compile packages and dependencies clean remove object files doc run godoc on package sources env print Go environment information fix run go tool fix on packages fmt run gofmt on package sources get download and install packages and dependencies install compile and install packages and dependencies list list packages run compile and run Go program test test packages tool run specified go tool version print Go version vet run go tool vet on packages
$ go env GOARCH="amd64" GOBIN="" GOCHAR="6" GOEXE="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/home/vladimiroff/go" GORACE="" GOROOT="/usr/lib/go" GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64" CC="gcc" GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread" CGO_ENABLED="1"
bin/ streak # command executable pkg/ linux_amd64/ code.google.com/p/goauth2/ oauth.a # package object src/ code.google.com/p/goauth2/ .hg/ # mercurial repository metadata oauth/ oauth.go # package source oauth_test.go # test source github.com/nf/ streak/ .git/ # git repository metadata oauth.go # command source streak.go # command source
Връщаме се обратно към Hello, world! примера:
package main import "fmt" func main() { fmt.Printf("Hello, world!\n") }
и се фокусираме върху
package main
Една програма на Go
е структура от пакети. Нямате шанс просто да хвърлите
едно парче код, в даден файл и то да тръгне.
n
файла могат да са в един пакет (демек filename
!= package
)fmt
, os
...Без значение от колко файла се състои:
Ако си мислите за "Lord of the rings", грешите. Говорим ви за main
.
В една програма имаме точно един пакет main
и при изпълнението ѝ се изпълнява функцията main
в него.
Програмата приключва, когато приключи изпълнението на функцията main
.
Тя не връща нищо.
Става с ключовата думичка import
, последвана от името на пакета, в кавички
import "fmt"
Ако искаме да импортнем няколко пакета:
import "fmt" import "os"
което go fmt би свел до
import ( "fmt" "os" )
package main import ( "fmt" "os" ) func main() { fmt.Printf("Hello, world!\n") }
Какво точно можем да използваме от импортнат пакет? Тук става забавно.
Даден идентификатор (било то на променлива, константа, тип, функция или
метод) е видим извън пакета си, тогава и само тогава когато името му започва с главна буква.
Наричаме ги exported
(на други места им викат public
).
Останалите са недостъпни (демек private
)
Имаме свободата да решим точно колко байта да е нашия тип:
... и разбира се имаме unsigned
:
uint
и int
uintptr
- нещо достатъчно голямо за да съдържа битовете на указател
Типовете int
и int32
са различни дори в архитектури на които int
е 32 бита. Същото е и за uint
.
var name string = "Чочко Чочков" var age uint8 = 25
Горното можем (и трябва) да запишем като:
var ( name string = "Чочко Чочков" age uint8 = 25 )
Ако са с един и същи тип, можем и така:
var name, age string = "Чочко Чочков", "двадесет и пет"
WTF! WTF! WTF! Защо типа е на грешното място!?
Можем да правим и така:
name := "Чочко Чочков" age := 25
package main import "fmt" name := "Киро" func main() { fmt.Printf("%s, защо да не може?\n", name) }
Не се грижим за това да си инициализираме стойностите. Всяка променлива в Go се инициализира по подразбиране:
var ( digit int // 0 digit *int // nil number float64 // 0.0 isIt bool // false name string // "" root complex64 // (0+0i) pipe chan <type> // nil )
Кастването работи, както очаквате:
number := 42 // (int=42.0) specificNumber := float64(number) // (float64=42.0)
С тази разлика, че нямате имплицитен каст:
number * specificNumber // (mismatched types int and float64)
Дефинирана стойност, която не се използва, води до грешка по време на компилация
Аналогично с var:
const ( name string = "Чочко Чочков" age uint8 = 25 )
Могат да бъдат само
Нали помните enum
?
const ( Monday = iota Tuesday Wednesday Thursday Friday Partyday Sunday )
if age < 13 { fmt.Print("Още не си тийнейджър") } else if age >= 13 && age < 20 { fmt.Print("В момента си тийнейджър") } else { fmt.Print("Минали са ти тийнейджърските години") }
(
и )
около условията{
е на същия ред с условието.} else {
трябва да са на един редelse if
, няма elseif
Добрия стар for
от C:
for i := 0; i < 20; i++ { fmt.Println(i) }
И точно както в C, някои от аргументите не са задължителни.
... някои да се чете като всички.
package main
import "fmt"
func main() {
for { fmt.Println("Can't stop me!") }
}
Забележка: Отварящата {
и тук е на същия ред с условието
Няма. for
покрива всичките му приложения.
Няма. for
покрива всичките му приложения.
switch { case age < 13: fmt.Print("Още не си тийнейджър") case age >= 13 && age < 20: fmt.Print("В момента си тийнейджър") default: fmt.Print("Минали са ти тийнейджърските години") }
_Няма_нужда_от_излишния break
Ако искаме да изпълним два поредни case-а
, използваме fallthrough
.
Все пак има break
, който е приложим за for
цикли.
continue
работи, точно както очаквате и където очаквате.
Да, има и такова.
Ако не знаете кога, не го ползвайте.
Към момента допускаме, че още не знаете кога => не го ползвате.
Q: Няма точка и запетая след всеки израз?
A: Всъщност има, но е имплицитна.
Сега си спомнете за правилото с отварящата {
.
Q: Интервали vs. Табове?
A: Един таб.