एक बहु-फ़ाइल गो परियोजना का आयोजन [बंद]


238

नोट: यह प्रश्न इस एक से संबंधित है , लेकिन गो इतिहास में दो वर्ष बहुत लंबा समय है।

विकास के दौरान गो परियोजना को व्यवस्थित करने का मानक तरीका क्या है?

मेरा प्रोजेक्ट एक एकल पैकेज है mypack, इसलिए मुझे लगता है कि मैंने सभी .go फ़ाइलों को एक mypackनिर्देशिका में रखा है।

लेकिन फिर, मैं विकास के दौरान इसका परीक्षण करना चाहूंगा main, इसलिए मुझे पैकेज की घोषणा करने के लिए कम से कम एक फ़ाइल की आवश्यकता है , ताकि मैं कर सकूंgo run trypack.go

मुझे इसे कैसे व्यवस्थित करना चाहिए? क्या मुझे go install mypackइसे आज़माने के लिए हर बार करने की ज़रूरत है?


14
यह संक्षिप्त विवरण भयानक है: youtube.com/watch?v=XCsL89YtqCs
मैट

यह समझने में एक और सहायक लिंक है कि पैकेज के साथ परियोजना को कैसे व्यवस्थित किया जाए। अधिकारी की तुलना में अनुसरण करना आसान हो जाता है कि कैसे लिखा जाना चाहिए मुझे लगता है कि कोड लिखें।
INNaN

नए गो मॉड्यूल सिस्टम के लिए, यह उत्तर मॉड्यूल संरचना को कवर करता है, एक मॉड्यूल के भीतर पैकेजों की व्यवस्था करता है, चाहे एकल रिपॉजिटरी आदि में कई मॉड्यूल हों या नहीं, आखिरकार, मॉड्यूल के लिए आधिकारिक "हाउ टू राइट गो कोड" इंट्रो दस्तावेज अपडेट किया जाएगा। , लेकिन अभी तक ऐसा नहीं हुआ है। (यदि आप Go के लिए नए हैं और Go के मॉड्यूल में नए हैं, तो यह अभी भी पढ़ने योग्य है कि "How to Write Go कोड" दस्तावेज़ को मॉड्यूल के बारे में अधिक पढ़ने से पहले पढ़ें, जिसमें से अधिकांश मॉड्यूल प्रलेखन GOPATH के साथ परिचितता को स्वीकार करता है)।
ठेठ 182

जवाबों:


171

मैं इस पेज पर गो कोड लिखने के बारे में समीक्षा करने की सलाह दूंगा

यह दोनों को बताता है कि अपनी परियोजना को एक go buildदोस्ताना तरीके से कैसे तैयार किया जाए, और परीक्षण कैसे लिखें। mainपैकेज का उपयोग करके टेस्ट को एक cmd होने की आवश्यकता नहीं है । वे बस प्रत्येक पैकेज के हिस्से के रूप में टेस्टएक्स नामित फ़ंक्शन हो सकते हैं, और फिर go testउन्हें खोज लेंगे।

आपके प्रश्न में उस लिंक में सुझाई गई संरचना थोड़ी पुरानी है, अब गो 1 के विमोचन के साथ आपको अब किसी pkgनिर्देशिका को नीचे रखने की आवश्यकता नहीं होगी src। केवल 3 युक्ति-संबंधी निर्देशिकाएं आपके GOPATH की जड़ में 3 हैं: बिन, pkg, src। नीचे src, आप बस अपनी परियोजना रख सकते हैं mypack, और नीचे है कि सभी .go फाइलें mypack_estest.go सहित।

go build फिर रूट स्तर pkg और बिन में निर्माण होगा।

तो आपका GOPATH इस तरह दिख सकता है:

~/projects/
    bin/
    pkg/
    src/
      mypack/
        foo.go
        bar.go
        mypack_test.go

export GOPATH=$HOME/projects

$ go build mypack
$ go test mypack

अद्यतन: जैसा कि> = 1.11 पर जाएं, मॉड्यूल सिस्टम अब टूलिंग का एक मानक हिस्सा है और GOPATH अवधारणा अप्रचलित होने के करीब है।


26
चर निर्यात करते समय ~ के बजाय $ HOME का उपयोग करें।
जोहान एस

6
चर निर्यात करते समय $ HOME की सिफारिश क्यों की जाती है?
425nesp

8
क्योंकि ~ एक परिवर्तनशील नहीं है, सिर्फ एक उपनाम है।
18

6
@ 425n जोहान से गलती हुई है - यह नहीं है। गोले भिन्न होते हैं, लेकिन पर्यावरण चर को सेट करते समय बैश फैलता है~ , और इसलिए व्यस्त बॉक्स उदाहरण के लिए बोर्न शेल करता है। इसे स्वयं आज़माएँ: export BOB=~ && env | grep ^BOBउपजेंगेBOB=/your/homedir
ऑस्टिन एडम्स

1
$HOMEतब और अधिक गोले में काम करता है ~, उदाहरण के लिएfish
hoijui

60

jdi के उपयोग के विषय में सही जानकारी है GOPATH। मुझे लगता है कि यदि आप एक द्विआधारी के रूप में अच्छी तरह से करना चाहते हैं तो आप निर्देशिका में एक अतिरिक्त स्तर जोड़ना चाहते हैं।

~/projects/src/
    myproj/
        mypack/
            lib.go
            lib_test.go
            ...
        myapp/
            main.go

चल रहा है go build myproj/mypackका निर्माण करेगा mypackयह निर्भरता चल के साथ पैकेज go build myproj/myappका निर्माण करेगा myappयह निर्भरता जो शायद शामिल के साथ बाइनरी mypackपुस्तकालय।


यह निश्चित रूप से समझ में आता है, अगर वह वास्तव में एक मुख्य cmd है। लगता है जैसे वह सिर्फ एक पुस्तकालय पैकेज बना रहा है।
जेडी

50

मैंने कई गो परियोजनाओं का अध्ययन किया है और इसमें काफी भिन्नता है। आप यह बता सकते हैं कि C से कौन आ रहा है और कौन जावा से आ रहा है, पूर्व के रूप में एक mainपैकेज में प्रोजेक्ट रूट डायरेक्टरी में सब कुछ के बारे में है , और बाद वाला सब कुछ एक srcडायरेक्टरी में रखता है । हालांकि न तो इष्टतम है। प्रत्येक के परिणाम हैं क्योंकि वे आयात पथों को प्रभावित करते हैं और दूसरे उन्हें कैसे पुन: उपयोग कर सकते हैं।

सर्वोत्तम परिणाम प्राप्त करने के लिए मैंने निम्नलिखित दृष्टिकोण पर काम किया है।

myproj/
  main/
    mypack.go
  mypack.go

कहाँ mypack.goहै package mypackऔर main/mypack.goहै (जाहिर है) package main

यदि आपको अतिरिक्त समर्थन फ़ाइलों की आवश्यकता है तो आपके पास दो विकल्प हैं। या तो उन सभी को रूट डायरेक्टरी में रखें, या एक उपनिर्देशिका में निजी समर्थन फाइलें डालें lib। उदाहरण के लिए

myproj/
  main/
    mypack.go
  myextras/
    someextra.go
  mypack.go
  mysupport.go

या

myproj.org/
  lib/
    mysupport.go
    myextras/
      someextra.go
  main/
    mypack.go
  mypage.go

फ़ाइलों को केवल एक libनिर्देशिका में रखा जाए, यदि वे किसी अन्य परियोजना द्वारा आयात किए जाने का इरादा नहीं रखते हैं। दूसरे शब्दों में, यदि वे निजी सहायता फाइलें हैं। libनिजी इंटरफेस से अलग सार्वजनिक होने के पीछे यही विचार है।

इस तरह से काम करना आपको myproj.org/mypackअन्य परियोजनाओं में कोड का पुन: उपयोग करने के लिए एक अच्छा आयात मार्ग देगा । आप का उपयोग करते हैं libतो आंतरिक समर्थन फ़ाइलों, एक आयात रास्ता है कि इस बात का संकेत है होगा myproj.org/lib/mysupport

परियोजना का निर्माण करते समय main/mypack, उदाहरण के लिए , उपयोग करें go build main/mypack। यदि आपके पास एक से अधिक निष्पादन योग्य हैं, तो आप mainअलग प्रोजेक्ट बनाने के बिना भी उन्हें अलग कर सकते हैं । जैसे main/myfoo/myfoo.goऔर main/mybar/mybar.go


14
मुहावरेदार cmd/nameOfMyExecutableमुख्य पैकेज के लिए एक उप-निर्देशिका का उपयोग करना है (केवल cmd/…अगर आपके पास कई कमांड हैं, तो देखें golang.org/x/tools/cmd; अन्यथा इसे चारों ओर स्वैप करना और main.goशीर्ष स्तर पर होना आम है)। आपके पास यह तरीका go installएक "मुख्य" (या "main.exe") निष्पादन योग्य बना देगा। इसके अलावा, मुहावरे के लिए internalउप-पैकेज के लिए एक उप-निर्देशिका का उपयोग पैकेज / कार्यक्रम के लिए होता है जो कि कहीं और इस्तेमाल करने के लिए नहीं है (यह उम्मीद है कि गो के भविष्य के संस्करण internalइस तरह से किए गए संकुल को आयात करने वाला कोई और नहीं होगा )।
डेव सी

21

मुझे यह समझने में बहुत उपयोगी लगता है कि गोलंग में कोड को व्यवस्थित करने के लिए यह अध्याय http://www.golang-book.com/11 Caleb Doxsey द्वारा लिखी गई पुस्तक का है।


13

गो परियोजनाओं के आयोजन का एक मानक तरीका प्रतीत नहीं होता है, लेकिन https://golang.org/doc/code.html अधिकांश परियोजनाओं के लिए एक सर्वोत्तम अभ्यास निर्दिष्ट करता है। jdi का जवाब अच्छा है लेकिन अगर आप github या bitbucket का उपयोग करते हैं और आपके पास अतिरिक्त पुस्तकालय भी हैं, तो आपको निम्नलिखित संरचना तैयार करनी चाहिए:

~/projects/
bin/
pkg/
src/
  github.com/
    username/
        mypack/
            foo.go
            bar.go
            mypack_test.go
        mylib/
            utillib.go
            utillib_test.go

इस तरह से करने से, आपके पास mylib के लिए एक अलग रिपॉजिटरी हो सकती है जिसे अन्य परियोजनाओं के लिए उपयोग किया जा सकता है और "गो गेट" द्वारा पुनर्प्राप्त किया जा सकता है। आपका mypack प्रोजेक्ट "github.com/username/mylib" का उपयोग करके आपकी लाइब्रेरी को आयात कर सकता है। अधिक जानकारी के लिए:

http://www.alexvictorchan.com/2014/11/06/go-project-structure/


6

फ़ाइलों को एक ही निर्देशिका में रखें और package mainसभी फ़ाइलों में उपयोग करें।

myproj/
   your-program/
      main.go
      lib.go

फिर भागो:

~/myproj/your-program$ go build && ./your-program

यह कैसे काम कर सकता है? आपका main.go पैकेज मुख्य होना चाहिए; संभवत: lib.go एक अलग पैकेज में है, तो गो टूल को शिकायत है कि आपके पास एक फ़ोल्डर में दो पैकेज नहीं हो सकते हैं।
I82Much

1
@ I82Much ओपी एक पैकेज, मुख्य कार्यक्रम को कई फाइलों में विभाजित करने का तरीका पूछता है। lib.go इस मामले में एक ही पैकेज में है।
गुस्ताव

स्पष्टीकरण के लिए आह धन्यवाद।
I82Much

@ गुस्ताव, मेरा भी यही सवाल है। ऐसा लगता है कि अगर मैं lib.go में मुख्य रूप से पैकेज रखता हूं, तो main.go में, मैं lib.go में परिभाषित फ़ंक्शन को कॉल नहीं कर सकता।
कियान चेन

@ElgsQianChen तरीकों को सार्वजनिक करने की आवश्यकता है, इसे एक बड़े अक्षर से शुरू करना होगा। जैसे MyMethod () या MyStruct {...}।
गुस्ताव

6

आइए खोजबीन करें कि कैसे go get repository_remote_urlकमांड प्रोजेक्ट संरचना का प्रबंधन करता है $GOPATH। अगर हम ऐसा करते हैं go get github.com/gohugoio/hugo, तो रिपॉजिटरी को क्लोन किया जाएगा

$ GOPATH / src / repository_remote / user_name / project_name


$ GOPATH / src / github.com/gohugoio/hugo

यह आपकी प्रारंभिक परियोजना पथ बनाने का एक अच्छा तरीका है । अब आइए अन्वेषक कि परियोजना के प्रकार क्या हैं और उनकी आंतरिक संरचना कैसे व्यवस्थित है। समुदाय की सभी गोलंग परियोजनाओं को इसके अंतर्गत वर्गीकृत किया जा सकता है

  • Libraries (कोई निष्पादन योग्य बायनेरिज़)
  • Single Project (केवल 1 निष्पादन योग्य बाइनरी शामिल है)
  • Tooling Projects (कई निष्पादन योग्य बायनेरिज़ शामिल हैं)

आमतौर पर गोलंग प्रोजेक्ट फाइलों को डीडीडी , पीओडी जैसे किसी भी डिजाइन सिद्धांतों के तहत पैक किया जा सकता है

अधिकांश उपलब्ध गो प्रोजेक्ट इस पैकेज ओरिएंटेड डिज़ाइन का अनुसरण करते हैं

पैकेज ओरिएंटेड डिज़ाइन डेवलपर को केवल अपने स्वयं के पैकेज के अंदर कार्यान्वयन को बनाए रखने के लिए प्रोत्साहित करता है, /internalपैकेज के अलावा जो पैकेज एक दूसरे के साथ संवाद नहीं कर सकते हैं


पुस्तकालय

  • डेटाबेस ड्राइवर , क्यूटी जैसी परियोजनाएं इस श्रेणी के तहत डाल सकती हैं।
  • कुछ पुस्तकालय जैसे रंग , अब बिना किसी अन्य पैकेज के एक सपाट संरचना का अनुसरण करते हैं।
  • इनमें से अधिकांश पुस्तकालय परियोजनाएं आंतरिक नामक एक पैकेज का प्रबंधन करती हैं ।
  • /internal पैकेज का उपयोग मुख्य रूप से अन्य परियोजनाओं से कार्यान्वयन को छिपाने के लिए किया जाता है।
  • कोई निष्पादन योग्य बायनेरिज़ न हो, इसलिए कोई भी फ़ाइल जिसमें मुख्य फ़ेंक नहीं है

 ~/$GOPATH/
    bin/
    pkg/
    src/
      repository_remote/
        user_name/
            project_name/
              internal/
              other_pkg/

एकल परियोजना

  • ह्यूगो , वगैरह जैसी परियोजनाओं में जड़ स्तर में एक ही मुख्य दुर्गंध है और
  • लक्ष्य एक एकल बाइनरी उत्पन्न करना है

टूलींग परियोजनाओं

  • कुबेरनेट्स , गो-एथेरियम जैसी परियोजनाओं में कई मुख्य फंक आयोजित किए जाते हैं जिन्हें सीएमडी कहा जाता है
  • cmd/ पैकेज बायनेरिज़ (उपकरण) की संख्या का प्रबंधन करता है जिसे हम बनाना चाहते हैं

 ~/$GOPATH/
    bin/
    pkg/
    src/
      repository_remote/
        user_name/
            project_name/
              cmd/
                binary_one/
                   main.go
                binary_two/
                   main.go
                binary_three/
                   main.go
              other_pkg/
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.