Go: импорт и видимость
Модератор: Olej
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Go: импорт и видимость
Потом появились модули. И, кроме версионности, модули повлияли на правила импортирования и видимости.
И возникает некоторая путаница... по крайней мере у меня. Нужно уточняться.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Go: импорт и видимость
Так это было:
Как писать Go-пакеты
27 авг 2019 в 12:47
Пакеты и модулиПакет Go состоит из Go-файлов, расположенных в одной и той же директории, в начале которых имеется одинаковое выражение package. Пакеты, подключаемые к программам, позволяют расширять их возможности.
Последнее обновление: 24.12.2017
А так это стало:Есть два типа пакетов: исполняемые (executable) и библиотеки (reusable). Для создания исполняемых файлов пакет должен иметь имя main. Все остальные пакеты не являются исполняемыми. При этом пакет main должен содержать функцию main, которая является входной точкой в приложение.
Определение модуля, файл go.mod
суббота, 6 июля 2019 г.
Модуль определяется деревом исходных файлов Go с файлом go.mod в корневом каталоге дерева. Каталог, содержащий файл go.mod, называется корнем модулем (module root). Обычно корень модуля также будет соответствовать корню хранилища исходного кода (но в общем случае это не обязательно). Модуль представляет собой набор всех пакетов Go в корневом каталоге модуля и его подкаталогах, но исключая поддеревья с собственными файлами go.mod.
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Go: импорт и видимость
Это вот всё в одном пакете:
- test1.go
Код: Выделить всё
package main
import "fmt"
func demo() {
fmt.Println("HI")
}
Код: Выделить всё
package main
func main() {
demo()
}
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/private$ go build *.go
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/private$ ls -l
итого 1860
-rwxrwxr-x 1 olej olej 1895359 фев 19 12:28 test1
-rw-rw-r-- 1 olej olej 66 фев 19 12:27 test1.go
-rw-rw-r-- 1 olej olej 41 фев 19 12:27 test2.go
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/private$ ./test1
HI
А вот так будет наоборот (хотя это и не имеет значения):
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/private$ go build test2.go test1.go
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/private$ ls -o
итого 1864
-rw-rw-r-- 1 olej 1514 фев 19 12:31 private.hist
-rw-rw-r-- 1 olej 66 фев 19 12:27 test1.go
-rwxrwxr-x 1 olej 1895351 фев 19 12:34 test2
-rw-rw-r-- 1 olej 41 фев 19 12:27 test2.go
Наконец, можно так:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/private$ go run test2.go test1.go
HI
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/private$ go run .
HI
- Вложения
-
- private.tgz
- (669 байт) 23 скачивания
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Go: импорт и видимость
Теперь хочу разнести пакет вызывающий и пакет библиотечный... И для библиотеки создаю отдельный каталог lib... Но сослаться на него в import вызывающего - нельзя, получите сообщение типа такого (то что имя пакета/каталога там названо ./digree не имеет значения ... так было):
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/packages$ go build *.go
head.go:8:5: "./digree" is relative, but relative import paths are not supported in module mode
found packages degree (digree.go) and main (head.go) in /home/olej/2024/own.BOOKs/BHV.Go.3/examples.work/packages
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/public$ go mod init public
go: creating new go.mod: module public
go: to add module requirements and sums:
go mod tidy
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/public$ cat go.mod
module public
go 1.22.0
- test2.go:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/public$ cat test2.go
package main
import "public/lib"
func main() {
lib1.Demo()
}
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/public$ cat lib/test1.go
package lib1
import "fmt"
func Demo() {
fmt.Println("HI")
}
Структура проекта теперь такая:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/public$ tree
.
├── go.mod
├── lib
│ └── test1.go
├── public.hist
└── test2.go
1 directory, 4 files
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/public$ go run test2.go
HI
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/public$ go run .
HI
Но ... Стоп
- import в вызывающем test2.go ссылается на "public/lib"
- а пакет в lib/test1.go назван как package lib1 (специально)
- т.е. импорту теперь (при наличии модулей) пофиг имена пакетов
- Вложения
-
- public.tgz
- (788 байт) 18 скачиваний
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Go: импорт и видимость
Небольшое дополнение... Импорту можно присвоить алиас, синоним...
Как-то нигде этого не усмотрел в документации, но ... подсмотрел у кого-то в кодах :
Меняю только вызывающий test2.go:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/public.ali$ cat test2.go
package main
import (
L "public/lib"
)
//import L "public/lib"
func main() {
L.Demo()
}
Поехали:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/public.ali$ go run .
HI
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/types/looking.for/public.ali$ go run test2.go
HI
- Вложения
-
- public.ali.tgz
- (793 байт) 22 скачивания
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Go: импорт и видимость
Пример куда интереснее ... головной модуль - вычисляет тригонометрические функции, но когда аргумент в градусах - передаёт одному пакету, а когда в радианах, то другому...
В главном (корневом) каталоге проекта:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ go mod init angels
go: creating new go.mod: module angels
go: to add module requirements and sums:
go mod tidy
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ cat go.mod
module angels
go 1.22.0
После этого структура каталогов/файлов становится такой:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ tree
.
├── angels.hist
├── digree
│ └── углы.go
├── go.mod
├── head.go
└── radian
└── рад1.go
2 directories, 5 files
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ cat head.go
package main
import (
"fmt"
"math"
)
import "angels/radian"
import "angels/digree"
func main() {
const угол1, угол2 = 30., 30. / 180 * math.Pi
fmt.Printf("синус %f градусов = %f\n", угол1, углы.Sin(угол1))
fmt.Printf("синус %f радиан = %f\n", угол2, радианы.Sin(угол2))
}
Имена каталогов (импорта) не совпадают ни с именами реализующих .go файлов, ни с именами пакетов названных в этих .go файлах исходников
2 отдельных каталога с отдельными пакетами...
Это пакет "радианы":
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ ls radian/
рад1.go
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ cat radian/рад1.go
package радианы
import "math"
func Cos(rd float64) float64 {
return math.Cos(rd)
}
func Sin(rd float64) float64 {
return math.Sin(rd)
}
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ ls digree/
углы.go
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ cat digree/углы.go
package углы
import "math"
var a2r func(dg float64) float64
func Cos(dg float64) float64 {
return math.Cos(a2r(dg))
}
func Sin(dg float64) float64 {
return math.Sin(a2r(dg))
}
func init() {
a2r = func(dg float64) float64 {
return dg / 180 * math.Pi
}
}
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ go run head.go
синус 30.000000 градусов = 0.500000
синус 0.523599 радиан = 0.500000
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels$ go run .
синус 30.000000 градусов = 0.500000
синус 0.523599 радиан = 0.500000
- Вложения
-
- angels.tgz
- (1.29 КБ) 23 скачивания
- Olej
- Писатель
- Сообщения: 21338
- Зарегистрирован: 24 сен 2011, 14:22
- Откуда: Харьков
- Контактная информация:
Go: импорт и видимость
Я попробовал 2 разных пакета (их файлы) разместить в одном общем каталоге (назвал его trigonom)...
И при сборке (или сразу при запуске) получаем вот такую ошибку:
Код: Выделить всё
olej@R420:~/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels2$ go run .
head.go:10:8: found packages радианы (рад1.go) and углы (углы.go) in /home/olej/2024/own.BOOKs/BHV.Go.3/examples.work/looking.for/angels2/trigonom
И тогда определение пакета, пожалуй, стоит переформулировать - как-то так:
- все *.go файлы пакета расположенных в одной и той же директории...
- и каждый отдельный пакет в своей собственной директории...
Имеет ли смысл иметь два пакета в одном каталоге?
У вас не может быть двух пакетов в каталоге, поэтому ошибка.
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 6 гостей