Как пакеты работают в golang

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

Из эффективного перехода в нем говорится:

"Другое соглашение состоит в том, что имя пакета является базовым именем его исходного каталога..."

Однако вышеприведенное описание, похоже, не заставляет идти или требуется. Таким образом, мне было интересно, если мне разрешено иметь несколько файлов с различными объявлениями пакетов вверху в базе той же. Если мне разрешено иметь несколько объявлений пакета в том же каталоге, как мне их затем импортировать и использовать каждый отдельно в одном файле? В принципе, я думаю, что одна из проблем, которую я имею, связана с формулировкой некоторых из учебников/документации go. Если это согласуется, то для меня подразумевается, что он НЕ применяется языком. Например, если программисты не записывают ключевое слово func для функции по соглашению. Мы пишем func, потому что иначе go будет кричать на вас, и он будет не компилироваться. Таким образом, я хочу пояснить это с помощью приведенного ниже примера (и, если возможно, изменить документацию для go, потому что это очень важно, на мой взгляд, как это можно сделать?).

Например, у меня есть три файла A.go, B.go, C.go, которые печатают функцию печати Print(), которая просто печатает a, b, c соответственно. Все они находятся в одном базовом каталоге, возможно, base. Затем у каждого есть другое объявление пакета package Apkg, package Bpkg, package Cpkg.

как бы вы могли пойти и импортировать их? Будет ли что-то следовать за работой?

package main

import(
    nameA "github.com/user_me/base/Apkg"
    nameB "github.com/user_me/base/Bpkg"
    nameC "github.com/user_me/base/Cpkg"
)

func main() {
    nameA.Print() \\prints a
    nameB.Print() \\prints b
    nameC.Print() \\prints c
}

или, может быть, нам даже не нужно указывать имя, если статусы пакета являются вершинами, уже разные:

package main

import(
    "github.com/user_me/base"
)

func main() {
    Apkg.Print() \\prints a
    Bpkg.Print() \\prints b
    Cpkg.Print() \\prints c
}

файл печати:

A.go:

//file at github.com.user_me/base and name A.go
package Apkg

import "fmt"

func Print(){
    fmt.Println("A")
}

B.go:

//file at github.com.user_me/base and name B.go
package Bpkg

import "fmt"

func Print(){
    fmt.Println("B")
}

C.go:   // файл на github.com.user_me/base и имя C.go   пакет Cpkg

import "fmt"

func Print(){
    fmt.Println("C")
}

Кроме того, если у вас может быть имя другое из base, может ли кто-нибудь уточнить мне, как фактически выполняется импорт? Если имя пакета package Apkg в базе, импорт должен быть import github.com/user_me/base или import github.com/user_me/base/Apkg или github.com/user_me/Apkg.

Я еще не тестировал это, но я скоро это сделаю. Импортная сделка в go была немного запутанной для меня и хотела бы получить ответ и поделиться им с миром.

Ответ 1

Нет, это 1 пакет на папку, поэтому вам придется иметь их:

$GOPATH/src/github.com/user_me/base/Apkg/a.go
$GOPATH/src/github.com/user_me/base/Bpkg/b.go
$GOPATH/src/github.com/user_me/base/Cpkg/c.go

Вы не можете даже построить его иначе:

┌─ [email protected] [/t/blah]                                                                                                         
└──➜ go build
can't load package: package .: found packages pkgA (blah1.go) and pkgB (blah2.go) in /tmp/blah

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

Кроме того, вы можете переименовать пакеты при импорте, например:

import (
   cr "crypto/rand"
   mr "math/rand"
)

Или ваша библиотека называется main (bad idea btw):

import m "github.com/user_me/base/main"