it-swarm.dev

Golang كيفية استيراد الحزم المحلية دون gopath؟

لقد استخدمت GOPATH ولكن بالنسبة لهذه المشكلة الحالية ، لا أواجهها. أريد أن أكون قادرًا على إنشاء حزم خاصة بمشروع:

myproject/
├── binary1.go
├── binary2.go
├── package1.go
└── package2.go

جربت عدة طرق ولكن كيف يمكنني الحصول على package1.go للعمل في binary1.go أو binary2.go وما إلى ذلك؟

فمثلا؛ أريد أن أكون قادراً على import "package1" ومن ثم أكون قادرًا على تشغيل go build binary1.go وكل شيء يعمل بشكل جيد دون أن يتم إلقاء الخطأ بأنه لا يمكن العثور على الحزمة على GOROOT أو GOPATH. السبب في أنني بحاجة إلى هذا النوع من الوظائف هو لمشاريع كبيرة الحجم ؛ لا أريد أن أشير إلى حزم أخرى متعددة أو احتفظ بها في ملف واحد كبير.

123
user1529891

الذهاب ملخص إدارة التبعية:

  • vgo إذا كانت إصدارك go: x >= go 1.11
  • dep أو vendor إذا كانت إصدارك go: go 1.6 >= x < go 1.11
  • يدويًا إذا كان إصدار go هو: x < go 1.6

تحرير 3: اذهب 1.11 لديه ميزة vgo والتي سوف تحل محلdep.

لاستخدام vgo ، راجع الوحدات النمطية الوثائق. TLDR أدناه:

export GO111MODULE=on
go mod init
go mod vendor # if you have vendor/ folder, will automatically integrate
go build

تقوم هذه الطريقة بإنشاء ملف يسمى go.mod في دليل مشاريعك. يمكنك بناء مشروعك باستخدام go build. إذا تم تعيين GO111MODULE=auto ، فلن يكون مشروعك في $GOPATH.


تحرير 2: طريقة البيع لا تزال صالحة وتعمل دون مشكلة. vendor إلى حد كبير عملية يدوية ، وبسبب هذا dep و vgo تم إنشاؤه.


تحرير 1: بينما تعمل طريقتي القديمة ، لم تعد الطريقة "الصحيحة" للقيام بذلك. يجب أن تستخدم بائع قدرات ، vgo ، أو dep (في الوقت الحالي) التي يتم تمكينها افتراضيًا في Go 1.6 ؛ نرى . يمكنك بشكل أساسي إضافة الحزم "الخارجية" أو "التابعة" ضمن دليل vendor ؛ عند التحويل البرمجي سيستخدم المترجم هذه الحزم أولاً.


وجدت. تمكنت من استيراد الحزمة المحلية باستخدام GOPATH عن طريق إنشاء مجلد فرعي من package1 ثم الاستيراد باستخدام import "./package1" في binary1.go و binary2.go النصية مثل:

binary1.go

...
import (
        "./package1"
      )
...

لذلك يبدو هيكل الدليل الحالي كما يلي:

myproject/
├── binary1.go
├── binary2.go
├── package1/
│   └── package1.go
└── package2.go

يجب أن أشير أيضًا إلى أن المسارات النسبية (على الأقل في الخطوة 1.5) تعمل أيضًا ؛ فمثلا:

import "../packageX"
144
user1529891

لا يوجد شيء اسمه "الحزمة المحلية". يعد تنظيم الحزم على القرص متعامدًا مع أي علاقة بين الوالدين والطفل. التسلسل الهرمي الحقيقي الوحيد الذي تشكله الحزم هو شجرة التبعية ، والتي في الحالة العامة لا تعكس شجرة الدليل.

مجرد استخدام

import "myproject/packageN"

ولا تحارب نظام البناء بدون سبب وجيه. لا يعد حفظ عشرات الأحرف لكل عملية استيراد في أي برنامج غير تافه سببًا جيدًا ، على سبيل المثال ، المشاريع التي لها مسارات استيراد نسبية لا يمكن الوصول إليها.

يحتوي مفهوم مسارات الاستيراد على بعض الخصائص المهمة:

  • يمكن أن تكون مسارات الاستيراد فريدة من نوعها على مستوى العالم.
  • بالتزامن مع GOPATH ، يمكن ترجمة مسار الاستيراد بشكل لا لبس فيه إلى مسار الدليل.
  • يمكن ترجمة أي مسار دليل ضمن GOPATH بشكل لا لبس فيه إلى مسار استيراد.

تم تدمير كل ما سبق باستخدام مسارات الاستيراد النسبية. لاتفعل ذلك.

ملاحظة: توجد أماكن قليلة في الكود القديم في اختبارات برنامج التحويل البرمجي Go التي تستخدم عمليات الاستيراد النسبية. هذا هو السبب الوحيد وراء دعم عمليات الاستيراد النسبية على الإطلاق.

59
zzzz

ربما كنت تحاول تشكيل الحزمة الخاصة بك. أفترض أن package1 و package2 يمثلان ، بطريقة ما ، جزءًا من نفس الحزمة ولكن لسهولة القراءة ، يتم تقسيمها إلى ملفات متعددة.

إذا كانت الحالة السابقة لك ، فيمكنك استخدام نفس اسم الحزمة في تلك الملفات المضاعفة وسيكون الأمر كما لو كان هناك نفس الملف.

هذا مثال:

add.go

package math

func add(n1, n2 int) int {
   return n1 + n2
}

subtract.go

package math

func subtract(n1, n2 int) int {
    return n1 - n2
}

donothing.go

package math

func donothing(n1, n2 int) int {
    s := add(n1, n2)
    s = subtract(n1, n2)
    return s
}

أنا لست خبيرا في Go وهذه هي أول وظيفة لي في StackOveflow ، لذلك إذا كان لديك بعض النصائح فسيتم استقبالها جيدًا.

40
Juan Jose Tugores

أواجه مشكلة مماثلة والحل الذي أستخدمه حاليًا يستخدم Go 1.11 modules. لدي البنية التالية

- projects
  - go.mod
  - go.sum
  - project1
    - main.go
  - project2
    - main.go
  - package1
    - lib.go
  - package2
    - lib.go

وأنا قادر على استيراد package1 و package2 من project1 و project2 باستخدام

import (
    "projects/package1"
    "projects/package2"
)

بعد تشغيل go mod init projects. يمكنني استخدام go build من أدلة project1 و project2 أو يمكنني استخدام go build -o project1/exe project1/*.go من دليل المشروعات.

الجانب السلبي لهذه الطريقة هو أن جميع المشاريع الخاصة بك في نهاية المطاف تقاسم نفس قائمة التبعية في go.mod. ما زلت أبحث عن حل لهذه المشكلة ، لكن يبدو أنها قد تكون أساسية.

11
Mad Wombat

لإضافة حزمة "محلية" إلى مشروعك ، أضف مجلدًا (على سبيل المثال "package_name"). ووضع ملفات التنفيذ الخاصة بك في هذا المجلد.

src/github.com/GithubUser/myproject/
 ├── main.go
 └───package_name
       └── whatever_name1.go
       └── whatever_name2.go

في package main الخاص بك ، قم بهذا:

import "github.com/GithubUser/myproject/package_name"

حيث package_name هو اسم المجلد ويجب أن يتطابق مع اسم الحزمة المستخدمة في الملفات ، أيًا كان اسم الصفحة أو any_name2.go. بمعنى آخر ، يجب أن تكون جميع الملفات ذات الدليل الفرعي من نفس الحزمة.

يمكنك إضافة المزيد من الدلائل الفرعية طالما حددت المسار الكامل للمجلد الأصلي في الاستيراد.

4
Homan