-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
27185fb
commit 748a65b
Showing
5 changed files
with
676 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
Go Beginners Innopolis | ||
Занятие 5: Пакеты и повторное использование кода, Тестирование | ||
5 Mar 2020 | ||
Tags: go, innopolis | ||
|
||
Emil Sharifullin | ||
Senior Software Engineer, SKB Kontur | ||
[email protected] | ||
@litleleprikon | ||
|
||
* В прошлых сериях | ||
|
||
- Как получить значение поля экземпляра структуры? | ||
- Как создать функцию, которая будет методом структуры? | ||
- Что такое получатель метода? | ||
- В чем разнича получателя по значению и получателя по указателю? | ||
- Что такое встраивание типов? | ||
- Что такое интерфейс? | ||
- Как создать горутину? | ||
- Что такое канал? | ||
- Что делает оператор select? | ||
|
||
* Пакеты и повторное использование кода | ||
|
||
* Пакеты и повторное использование кода | ||
|
||
*DRY* — «Don't Repeat Yourself» — (акроним, в переводе с английского) — «не повторяйтесь!». | ||
|
||
Go поддерживает ещё один механизм для повторного использования кода, кроме функций — пакеты. | ||
|
||
import "fmt" | ||
|
||
Пакеты удобны, потому что позволяют: | ||
|
||
- Снизить вероятность дублирование имён функций, что позволяет именам быть простыми и краткими | ||
- Организовывать код для упрощения поиска повторно используемых конструкций | ||
- Ускорить компиляцию, так как мы должны перекомпилировать только части программы. Несмотря на то, что мы используем пакет fmt, мы не должны перекомпилировать его при каждом использовании | ||
|
||
* Создание пакета | ||
|
||
.code src/packages/first/math/math.go HL01 | ||
|
||
.play src/packages/first/main.go HL01 | ||
|
||
* Создание пакета | ||
*math* является встроенным пакетом, но так как пакеты Go используют иерархические наименование, мы можем перекрыть уже используемое наименование, в данном случае настоящий пакет *math* и будет называться *math*, а наш — *github.com/GDG-Cloud-Innopolis/Go-begginners/l5/src/packages/first/math*. | ||
|
||
Когда мы импортируем библиотеку, мы используем её полное наименование import *"github.com/GDG-Cloud-Innopolis/Go-begginners/l5/src/packages/first/math"*, но внутри файла main.go мы используем только последнюю часть названия — *package* *math*. | ||
|
||
Мы используем только краткое имя math когда мы обращаемся к функциям в нашем пакете. Если же мы хотим использовать оба пакета, то мы можем использовать псевдоним: | ||
|
||
import m "golang-book/chapter11/math" | ||
|
||
* Доступ к сущностям в пакете | ||
|
||
Возможно вы заметили, что каждая функция в пакете начинается с заглавной буквы. Любая сущность языка Go, которая начинается с заглавной буквы, означает, что другие пакеты и программы могут использовать эту сущность. Если бы мы назвали нашу функцию average, а не Average, то наша главная программа не смогла бы обратиться к ней. | ||
|
||
Рекомендуется делать явными только те сущности нашего пакета, которые могут быть использованы другими пакетами, и прятать все остальные служебные функции, не используемые в других пакетах. Данный подход позволяет производить изменения в скрытых частях пакета без риска нарушить работу других программ, и это облегчает использование нашего пакета | ||
|
||
Имена пакетов совпадают с директориями, в которых они размещены. Данное правило можно обойти, но делать это нежелательно. | ||
|
||
* Работа с пакетами | ||
|
||
Изначально пакеты скачивались из любого гит репозитория из ветки master | ||
|
||
Делаем *go* *get* - скачивается свежий код из мастера подключаемого пакета | ||
|
||
Легко и просто работать с пакетами, так же легко сломать билд новой версией пакета | ||
|
||
Пакеты скачавались в *$GOPATH* и проекты можно было запускать только внутри *$GOPATH* | ||
|
||
Фиксируем исходники всех зависимостей в папке vendor или используем сторонний тулинг для управления зависимостями | ||
|
||
* Модули | ||
|
||
Были представлены в 2018 году и поддерживают версионирование | ||
|
||
$ go mod init github.com/GDG-Cloud-Innopolis | ||
|
||
Модуля должен быть файл *go.mod*, в котором содержится описание модуля и также его зависимости | ||
|
||
.code ../go.mod | ||
|
||
$ git tag v1.0.0 | ||
$ git push --tags | ||
|
||
При изменении мажорной версии пакета, он получает новое имя, к примеру: | ||
|
||
github.com/googleapis/gax-go @ master branch | ||
/go.mod → module github.com/googleapis/gax-go | ||
/v2/go.mod → module github.com/googleapis/gax-go/v2 | ||
|
||
* Документация к коду | ||
|
||
Go позволяет автоматически создавать документацию к пользовательским пакетам так же, как и документировать стандартные пакеты. Запустите эту команду в терминале: | ||
|
||
$ go doc github.com/GDG-Cloud-Innopolis/Go-begginners/l5/src/packages/first/math Average | ||
|
||
И получим такой вот ответ | ||
|
||
package math // import "github.com/GDG-Cloud-Innopolis/Go-begginners/l5/src/packages/first/math" | ||
|
||
func Average(xs []float64) float64 | ||
Average is a function that count average between numbers | ||
|
||
.link https://pkg.go.dev/github.com/GDG-Cloud-Innopolis/[email protected] | ||
|
||
* Тестирование | ||
|
||
* Тестирование | ||
|
||
Писать программы — не просто. Даже самые лучшие программисты, зачастую, не в состоянии написать программу так, чтобы она работала как положено в любых случаях. Поэтому, важной частью процесса разработки является тестирование. Написание тестов для нашего кода является отличным способом повышения его качества и стабильности. | ||
|
||
Go содержит специальные инструменты, призванные облегчить написание тестов, так что давайте напишем несколько тестов для пакета, который мы создали в предыдущей главе. В папке создайте файл под именем math_test.go, который будет содержать следующее: | ||
|
||
* Тестирование | ||
|
||
.code src/packages/first/math/math_test.go /START ONE /,/END ONE/ | ||
|
||
$ go test | ||
=== RUN TestAverage | ||
--- PASS: TestAverage (0.00s) | ||
PASS | ||
ok github.com/GDG-Cloud-Innopolis/Go-begginners/l5/src/packages/first/math 0.101s | ||
|
||
* Тестирование | ||
|
||
.code src/packages/first/math/math_test.go /START TWO /,/END TWO/ | ||
|
||
* Тестирование | ||
|
||
.code src/packages/first/math/math_test.go /END TWO /,/END THREE/ | ||
|
||
go test -v | ||
=== RUN TestAverage | ||
--- PASS: TestAverage (0.00s) | ||
=== RUN TestAverage1 | ||
=== RUN TestAverage1/Two_numbers | ||
=== RUN TestAverage1/Equal_numbers | ||
--- PASS: TestAverage1 (0.00s) | ||
--- PASS: TestAverage1/Two_numbers (0.00s) | ||
--- PASS: TestAverage1/Equal_numbers (0.00s) | ||
PASS | ||
ok github.com/GDG-Cloud-Innopolis/Go-begginners/l5/src/packages/first/math 0.473s | ||
|
||
* Бенчмарки | ||
|
||
.code src/packages/first/math/math_test.go /START FOUR /,/END FOUR/ | ||
|
||
go test -bench=. | ||
goos: darwin | ||
goarch: amd64 | ||
pkg: github.com/GDG-Cloud-Innopolis/Go-begginners/l5/src/packages/first/math | ||
BenchmarkAverage10-8 100000000 10.5 ns/op | ||
PASS | ||
ok github.com/GDG-Cloud-Innopolis/Go-begginners/l5/src/packages/first/math 1.523s | ||
|
||
* Задачка | ||
|
||
Вынести функцию Calc из третьего урока в Модуль(https://play.golang.org/p/G6YMZMHnotU). Покрыть модуль тестами и написать документацию. Написать в Go Playground программу, которая использует вашу функцию | ||
|
||
.link https://play.golang.org/p/_6SP-Dj79fY | ||
|
||
.image img/qrcode-6.svg 300 _ |
Oops, something went wrong.