Базовые компоненты программы на Go: пакеты, функции, переменные и константы.

Каждая программа на Go состоит из пакетов и начинает работу в пакете main.
Программа использует импорт пакетов, по соглашению имя пакета совпадает с последним элементом пути импорта. Например, пакет “math/rand” состоит из файлов, которые начинаются с оператора package “rand”.
Хорошим тоном считается использование группированного оператора import, который объединяет все импорты в один с помощью круглых скобок.

import(
   "fmt"
   "math"
)

В Go идентификатор экспортируется, если он начинается с заглавной буквы: Temperature, Humidity - экспортируемые идентификаторы, а temperature, humidity - не экспортируемые. При импорте пакета можно ссылаться только на его экспортируемые идентификаторы. Любые не экспортированные идентификаторы недоступны за пределами пакета.

Функция может принимать один или несколько аргументов, тип указывается после имени переменной:

func add(x int, y int) int {
	return x + y
}

Когда два или более последовательных параметра функции имеют одинаковый тип, его можно указать только для последнего:

func add(x, y int) int {
	return x + y
}

Функция может возвращать несколько результатов, например, функция swap возвращает две строки:

func swap(x, y string) (string, string) {
	return y, x
}

В Go возвращаемые значения могут быть именованными. В этом случае они расцениваются как переменные объявленные в начале функции. Эти имена используются для документирования смысла возвращаемых значений.
Оператор return без аргументов возвращает именованные значения, что известно как “пустой” возврат:

func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return
}

Такой способ возврата значений можно использовать только в коротких функциях, так как в более длинных функциях это может ухудшить читаемость.

Переменные в Go объявляют при помощи операторов var или :=.
Оператор var объявляет список переменных и может быть использован на уровне пакета или функции. Как и в случае с аргументами функции, тип указывается после имени переменной или после нескольких последовательных имен одинакового типа:

package main

import "fmt"

var c, python, java bool

func main() {
	var i int
	fmt.Println(i, c, python, java)
}

Объявление переменной может включать инициализирующее значение, по одному на каждую переменную. Если инициализирующее значение присутствует, то тип может быть опущен, переменная получит тип этого значения:

var i, j int = 1, 2

Внутри функции, краткий оператор присваивания := с неявным типом может быть использован вместо объявления с помощью var. Вне функции, каждый оператор должен начинаться с ключевого слова (var, func, …), и поэтому конструкция := недоступна.

package main

import "fmt"

func main() {
	var i, j int = 1, 2
	k := 3
	c, python, java := true, false, "no!"

	fmt.Println(i, j, k, c, python, java)
}

Базовые типы Go:

bool

string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // псевдоним для uint8

rune // псевдоним для int32
     // представляет Unicode код

float32 float64

complex64 complex128

Переменные нескольких типов при объявлении могут быть сгруппированы в блоки, так же как и операторы import:

var (
	ToBe   bool       = false
	MaxInt uint64     = 1<<64 - 1
	z      complex128 = cmplx.Sqrt(-5 + 12i)
)

Если нет особой причины использовать целочисленное значение конкретного размера или беззнаковое значение, то следует использовать тип int.

Переменным объявленным без указания начального значения автоматически присваивается нулевое значение:

  • 0 для числовых типов,
  • false для булевого типа,
  • "" (пустая строка) для строк.

В отличие от ‘C’, в Go допускается только явного приведение типов.

Выражение T(v) приводит значение v к типу T.

Примеры для числовых типов:

var (
	i int = 42
	f float64 = float64(i)
	u uint = uint(f)
)

или

i := 42
f := float64(i)
u := uint(f)

При объявлении переменной без явного указания типа (с помощью := или var =), тип переменной выводится из значения в правой части выражения.
Когда правой части выражения уже присвоен тип, новая переменная получает такой же тип:

var i int
j := i // j это int

Но когда правая часть содержит нетипизированную числовую константу, новая переменная может быть int, float64, или complex128 в зависимости от точности константы:

i := 42           // int
f := 3.142        // float64
g := 0.867 + 0.5i // complex128

Константы объявляются как переменные, но с помощью ключевого слова const.
Константы могут иметь символьные, строковые, булевые или числовые значения. Константы не могут быть объявленные с помощью синтаксиса :=.
Числовые константы это значения высокой точности. Нетипизированная константа принимает тип, необходимый в ее контексте.