понедельник, 24 июня 2019 г.

Go модули: создание нового модуля

Создайте новый пустой каталог где-нибудь за пределами $GOPATH/src, перейдите в этот каталог, а затем создайте новый исходный файл hello.go:

package hello

func Hello() string {
    return "Hello, world."
}

Также напишем тест в hello_test.go:

package hello

import "testing"

func TestHello(t *testing.T) {
    want := "Hello, world."
    if got := Hello(); got != want {
        t.Errorf("Hello() = %q, want %q", got, want)
    }
}

На данный момент каталог содержит пакет, но не модуль, потому что нет файла go.mod. Если бы мы работали в /home/gopher/hello и запускали go test сейчас, мы бы увидели:

$ go test
PASS
ok      _/home/gopher/hello    0.020s
$

Последняя строка суммирует общий пакетный тест. Поскольку мы работаем за пределами $GOPATH, а также за пределами любого модуля, команда go не знает пути импорта для текущего каталога и создает поддельный путь на основе имени каталога: _/home/gopher/hello.

Сделаем текущий каталог корневым модулем с помощью go mod init, а затем снова попробуем go test:

$ go mod init example.com/hello
go: creating new go.mod: module example.com/hello
$ go test
PASS
ok      example.com/hello    0.020s
$

Вы написали и протестировали свой первый модуль.

Команда go mod init записала файл go.mod:

$ cat go.mod
module example.com/hello

go 1.12
$

Файл go.mod отображается только в корне модуля. Пакеты в подкаталогах имеют пути импорта, состоящие из пути модуля плюс путь к подкаталогу. Например, если бы мы создали подкаталог world, нам не нужно было бы запускать go mod init там. Пакет автоматически распознается как часть модуля example.com/hello с указанием пути импорта example.com/hello/world.


Читайте также:


Go модули

Go 1.11 и 1.12 включают предварительную поддержку модулей, новую систему управления зависимостями Go, которая делает информацию о версии зависимостей явной и простой в управлении. В последующих постах будут освещены основные операции, необходимые для начала работы с модулями.

Модуль (module) представляет собой набор пакетов Go, хранящихся в файловом дереве с файлом go.mod в его корне. Файл go.mod определяет для каждого модуля путь к модулю, который также является путем импорта, используемым для корневого каталога, и его требования к зависимостям, которые являются другими модулями, необходимыми для успешной сборки. Каждое требование к зависимости записывается в виде пути к модулю и конкретной семантической версии.

Начиная с Go 1.11, команда go позволяет использовать модули, когда текущий или любой родительский каталог имеет go.mod, при условии, что каталог находится за пределами $GOPATH/src. (Внутри $GOPATH/src для совместимости команда go по-прежнему выполняется в старом режиме GOPATH, даже если обнаружен go.mod.) Начиная с Go 1.13, режим модуля будет использоваться по умолчанию.

В последующих постах рассматривается последовательность общих операций, возникающих при разработке кода Go с модулями:


Читайте также:


Установка Go

Загрузите дистрибутив Go

Скачать Go. Нажмите здесь, чтобы посетить страницу загрузки

Официальные бинарный дистрибутивы доступны для операционных систем FreeBSD (версия 10-STABLE и выше), Linux, macOS (10.10 и выше) и Windows, а также 32-битных (386) и 64-битных (amd64) процессорных архитектур x86.

Если бинарный дистрибутив недоступен для вашей комбинации операционной системы и архитектуры, попробуйте установить из исходного кода или установить gccgo вместо gc.

Системные требования

Бинарный дистрибутивы Go доступны для следующих поддерживаемых операционных систем и архитектур. Пожалуйста, убедитесь, что ваша система соответствует этим требованиям, прежде чем продолжить. Если вашей ОС или архитектуры нет в списке, вы можете установить ее из исходного кода или использовать вместо нее gccgo.

Операционная система                Архитектуры             Примечания

FreeBSD 10.3                        amd64, 386              Debian GNU/kFreeBSD не поддерживается
или более поздняя версия   

Linux 2.6.23                        amd64, 386, arm,        CentOS / RHEL 5.x не поддерживается.
или более поздняя версия с glibc    arm64, s390x, ppc64le   Установите из исходного кода для другого libc.
 
macOS 10.10                         amd64                   использует clang или gcc*, который 
или более поздняя версия                                    поставляется с Xcode** для поддержки cgo
 
Windows 7, Server 2008R2            amd64, 386              используют MinGW gcc*. 
или новее                                                   Нет необходимости в cygwin или msys.
  

* Компилятор C требуется, только если вы планируете использовать cgo.

** Вам нужно только установить инструменты командной строки для Xcode. 
Если вы уже установили Xcode 4.3+, вы можете установить его на вкладке 
«Компоненты» панели настроек «Загрузки».

Установите инструменты Go

Если вы обновляете более старую версию Go, вы должны сначала удалить существующую версию.

Tarboll'ы для Linux, macOS и FreeBSD

Загрузите архив и распакуйте его в /usr/local, создав дерево Go в /usr/local/go. Например:

tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz

Выберите файл архива, подходящий для вашей установки. Например, если вы устанавливаете Go версии 1.2.1 для 64-битной x86 в Linux, то нужный вам архив называется go1.2.1.linux-amd64.tar.gz.

(Обычно эти команды должны запускаться от имени пользователя root или через sudo.)

Добавьте /usr/local/go/bin в переменную окружения PATH. Вы можете сделать это, добавив эту строку в ваш /etc/profile (для общесистемной установки) или в $HOME/.profile:

export PATH=$PATH:/usr/local/go/bin

Примечание. Изменения, внесенные в файл профиля, могут не применяться до следующего входа в систему. Чтобы немедленно применить изменения, просто запустите команды оболочки напрямую или выполните их из профиля, используя команду, например source $HOME/.profile.

Установщик пакета macOS

Загрузите файл пакета, откройте его и следуйте инструкциям по установке инструментов Go. Пакет устанавливает дистрибутив Go в /usr/local/go.

Пакет должен поместить каталог /usr/local/go/bin в переменную среды PATH. Вам может потребоваться перезапустить все открытые сеансы терминала, чтобы изменения вступили в силу.

Windows

Проект Go предоставляет два варианта установки для пользователей Windows (помимо установки из источника): zip-архив, в котором требуется установить некоторые переменные среды, и установщик MSI, который автоматически настраивает установку.

Установщик MSI

Откройте файл MSI и следуйте инструкциям по установке инструментов Go. По умолчанию установщик помещает дистрибутив Go в c:\Go.

Установщик должен поместить каталог c:\Go\bin в переменную окружения PATH. Вам может потребоваться перезапустить любые открытые командные строки, чтобы изменения вступили в силу.

Zip архив

Загрузите zip-файл и распакуйте его в каталог по вашему выбору (предлагается c:\Go).

Добавьте подкаталог bin вашего корневого каталога Go (например, c:\Go\bin) в переменную среды PATH.

Установка переменных среды под Windows

В Windows вы можете установить переменные среды с помощью кнопки «Переменные среды» на вкладке «Дополнительно» панели управления «Система». Некоторые версии Windows предоставляют эту панель управления через параметр «Дополнительные параметры системы» на панели управления «Система».

Проверьте вашу установку

Убедитесь, что Go установлен правильно, настроив рабочее пространство и собрав простую программу следующим образом.

Создайте свой каталог рабочей области, $HOME/go. (Если вы хотите использовать другой каталог, вам нужно установить переменную среды GOPATH.)

Затем создайте в вашей рабочей области каталог src/hello, и в этом каталоге создайте файл с именем hello.go, который выглядит следующим образом:

package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}

Затем соберите его с помощью инструмента go:

$ cd $HOME/go/src/hello
$ go build

Команда выше создаст исполняемый файл с именем hello в каталоге вместе с вашим исходным кодом. Выполните его, чтобы увидеть приветствие:

$ ./hello
hello, world

Если вы видите сообщение "hello, world", значит, ваша установка Go работает.

Вы можете запустить go install, чтобы установить бинарный файл в каталог bin вашего рабочего пространства, или выполните команду go clean -i, чтобы удалить его.

Установка дополнительных версий Go

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

$ go get golang.org/dl/go1.10.7
$ go1.10.7 download

Недавно загруженную версию можно использовать как go:

$ go1.10.7 version
go version go1.10.7 linux/amd64

Все версии Go, доступные с помощью этого метода, перечислены на странице загрузки. Вы можете узнать, где установлена каждая из этих дополнительных версий Go, взглянув на GOROOT; например, go1.10.7 env GOROOT. Чтобы удалить загруженную версию, просто удалите ее каталог GOROOT и бинарный файл goX.Y.Z.

Удаление Go

Чтобы удалить существующую установку Go из вашей системы, удалите каталог go. Обычно это /usr/local/go под Linux, macOS и FreeBSD или c:\Go под Windows.

Вам также следует удалить каталог Go bin из переменной окружения PATH. Под Linux и FreeBSD вы должны отредактировать /etc/profile или $HOME/.profile. Если вы установили Go с пакетом macOS, вам следует удалить файл /etc/paths.d/go. Пользователям Windows следует прочитать раздел о настройке переменных среды в Windows.


Читайте также:


воскресенье, 23 июня 2019 г.

Спецификация Go: системные замечания, пакет unsafe

Встроенный пакет unsafe, известный компилятору и доступный по пути импорта "unsafe", предоставляет средства для низкоуровневого программирования, включая операции, которые нарушают систему типов. Пакет, использующий unsafe, должен быть проверен вручную для безопасности типа и не может быть переносимым. Пакет предоставляет следующий интерфейс:

package unsafe

// сокращение для произвольного типа Go; 
// это не настоящий тип
type ArbitraryType int  

type Pointer *ArbitraryType

func Alignof(variable ArbitraryType) uintptr
func Offsetof(selector ArbitraryType) uintptr
func Sizeof(variable ArbitraryType) uintptr

Pointer является типом указателя, но значение Pointer не может быть разыменовано. Любой указатель или значение базового типа uintptr может быть преобразовано в тип базового типа Pointer и наоборот. Эффект преобразования между Pointer и uintptr определяется реализацией.

var f float64
bits = *(*uint64)(unsafe.Pointer(&f))

type ptr unsafe.Pointer
bits = *(*uint64)(ptr(&f))

var p ptr = nil

Функции Alignof и Sizeof принимают выражение x любого типа и возвращают выравнивание или размер, соответственно, гипотетической переменной v, как если бы v было объявлено через var v = x.

Функция Offsetof принимает (возможно заключенный в скобки) селектор s.f, обозначающий поле f структуры, обозначенной s или *s, и возвращает смещение поля в байтах относительно адреса структуры. Если f является встроенным полем, оно должно быть доступно без косвенных указателей через поля структуры. Для структуры s с полем f:

uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))

Компьютерные архитектуры могут требовать выравнивания адресов памяти; то есть, чтобы адреса переменной были кратны фактору, выравнивание типа переменной. Функция Alignof принимает выражение, обозначающее переменную любого типа, и возвращает выравнивание (тип) переменной в байтах. Для переменной x:

uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0

Вызовы Alignof, Offsetof и Sizeof являются константными выражениями времени компиляции типа uintptr.

Размер и гарантия выравнивания

Для числовых типов гарантируются следующие размеры:

тип                                 размер в байтах

byte, uint8, int8                     1
uint16, int16                         2
uint32, int32, float32                4
uint64, int64, float64, complex64     8
complex128                           16

Следующие минимальные свойства выравнивания гарантированы:

  1. Для переменной x любого типа: unsafe.Alignof(x) по крайней мере 1.
  2. Для переменной x типа struct: unsafe.Alignof(x) является наибольшим из всех значений unsafe.Alignof(x.f) для каждого поля f из x, но не менее 1.
  3. Для переменной x типа массива: unsafe.Alignof(x) совпадает с выравниванием переменной типа элемента массива.

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


Читайте также:


Спецификация Go: паника во время выполнения (run-time panic)

Ошибки выполнения, такие как попытка индексирования массива за пределами границ, вызывают панику во время выполнения, эквивалентную вызову встроенной функции panic со значением определяемого реализацией типа интерфейса runtime.Error. Этот тип удовлетворяет предварительно объявленному интерфейсу типа error. Точные значения ошибок, которые представляют различные условия ошибок времени выполнения, не определены.

package runtime

type Error interface {
    error
    // и возможно другие методы
}


Читайте также:


Спецификация Go: ошибки

Предопределенный тип error определен как

type error interface {
    Error() string
}

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

func Read(f *File, b []byte) (n int, err error)


Читайте также:


Спецификация Go: выполнение программы

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

func main() { … }

Выполнение программы начинается с инициализации основного пакета и последующего вызова функции main. Когда этот вызов функции возвращается, программа завершается. Он не ждет завершения других (неосновных) программ.


Читайте также: