Go разработан как язык, который поощряет хорошие инженерные практики. Одной из этих практик, позволяющих создавать высококачественное программное обеспечение, является повторное использование кода, называемое DRY — «Don't Repeat Yourself» — (акроним, в переводе с английского) — «не повторяйтесь!». Как мы уже видели в 7 главе, функции являются первым уровнем повторного использование кода. Но Go поддерживает ещё один механизм для повторного использования кода — пакеты. Почти любая программа, которую мы видели, включает эту строку:
import "fmt"
fmt
— это имя пакета, включающего множество функций, связанных с
форматированием строк и выводом на экран. Данный метод распространения кода
обусловлен тремя причинами:
Снижение вероятности дублирование имён функций, что позволяет именам быть простыми и краткими
Организация кода для упрощения поиска повторно используемых конструкций
Ускорение компиляции, так как мы должны перекомпилировать только части программы. Несмотря на то, что мы используем пакет
fmt
, мы не должны перекомпилировать его при каждом использовании
Создание пакета
Использовать пакеты имеет смысл, только когда они востребованы отдельной программой. Без неё использовать пакеты невозможно.
Давайте создадим программу, которая будет использовать наш пакет. Создадим
директорию в ~/Go/src/golang-book
под названием chapter11
. В ней создадим
файл main.go
с этим кодом:
package main
import "fmt"
import "golang-book/chapter11/math"
func main() {
xs := []float64{1,2,3,4}
avg := math.Average(xs)
fmt.Println(avg)
}
А теперь создадим ещё одну директорию внутри chapter11
под названием math
В ней мы создадим файл math.go
с этим кодом:
package math
func Average(xs []float64) float64 {
total := float64(0)
for _, x := range xs {
total += x
}
return total / float64(len(xs))
}
C помощью терминала в папке math
запустите команду go install
. В результате
файл math.go
скомпилируется в объектный файл ~/Go/pkg/os_arch/golang-book/chapter11/math.a
(при этом, os
может быть Windows
, a arch
, например, — amd64)
Теперь вернёмся в директорию chapter11
и выполним go run main.go
. Программа
выведет 2.5
на экран. Подведём итоги:
math
является встроенным пакетом, но так как пакеты Go используют иерархические наименование, мы можем перекрыть уже используемое наименование, в данном случае настоящий пакетmath
и будет называтьсяmath
, а наш —golang-book/chapter11/math
.Когда мы импортируем библиотеку, мы используем её полное наименование
import "golang-book/chapter11/math"
, но внутри файлаmath.go
мы используем только последнюю часть названия —package math
.Мы используем только краткое имя
math
когда мы обращаемся к функциям в нашем пакете. Если же мы хотим использовать оба пакета, то мы можем использовать псевдоним:import m "golang-book/chapter11/math" func main() { xs := []float64{1,2,3,4} avg := m.Average(xs) fmt.Println(avg) }
В этом коде
m
— псевдоним.Возможно вы заметили, что каждая функция в пакете начинается с заглавной буквы. Любая сущность языка Go, которая начинается с заглавной буквы, означает, что другие пакеты и программы могут использовать эту сущность. Если бы мы назвали нашу функцию
average
, а неAverage
, то наша главная программа не смогла бы обратиться к ней.Рекомендуется делать явными только те сущности нашего пакета, которые могут быть использованы другими пакетами, и прятать все остальные служебные функции, не используемые в других пакетах. Данный подход позволяет производить изменения в скрытых частях пакета без риска нарушить работу других программ, и это облегчает использование нашего пакета
Имена пакетов совпадают с директориями, в которых они размещены. Данное правило можно обойти, но делать это нежелательно.
Документация к коду
Go позволяет автоматически создавать документацию к пользовательским пакетам так же, как и документировать стандартные пакеты. Запустите эту команду в терминале:
godoc golang-book/chapter11/math Average
И вы увидите информацию о функции, которую мы только что написали. Мы можем улучшить документацию, добавив комментарий перед функцией:
// Найти среднее в массиве чисел.
func Average(xs []float64) float64 {
Если вы запустите go install
, а потом перезапустите:
godoc golang-book/chapter11/math Average
то вы увидите наш комментарий — Найти среднее в массиве чисел
. Также вы можете
увидеть документацию на интернет-странице, запустив в терминале команду:
godoc -http=":6060"
и открыв этот адрес в браузере http://localhost:6060/pkg/
.
Вы увидите документацию по всем пакетам, установленным в системе, в том числе и про наш пакет.
Задачи
Зачем мы используем пакеты?
Чем отличаются программные сущности, названные с большой буквы? То есть, чем
Average
отличается отaverage
?Что такое псевдоним пакета и как его сделать?
Мы скопировали функцию
Average
из главы 7 в наш новый пакет. СоздайтеMin
иMax
функции для нахождения наименьших и наибольших значений в срезах дробных чисел типаfloat64
.Напишите документацию к функциям
Min
иMax
из предыдущей задачи.