2015-09-18 6 views
5

मैं कोड के ब्लॉक से वर्तमान GOPATH कैसे प्राप्त करूं?कोड से वर्तमान GOPATH कैसे प्राप्त करें

runtime केवल GOROOT है:

// GOROOT returns the root of the Go tree. 
// It uses the GOROOT environment variable, if set, 
// or else the root used during the Go build. 
func GOROOT() string { 
    s := gogetenv("GOROOT") 
    if s != "" { 
     return s 
    } 
    return defaultGoroot 
} 

मैं एक समारोह है कि GOROOTGOPATH के साथ बदल दिया गया है कर सकता है, लेकिन इसके लिए एक buildin है?

उत्तर

10

उपयोग os.Getenv

डॉक्स से:

Getenv कुंजी द्वारा नामित वातावरण चर का मान प्राप्त करता है। यह मान देता है, जो वैरिएबल मौजूद नहीं है, जो खाली होगा।

उदाहरण:

package main 

import (
    "fmt" 
    "go/build" 
    "os" 
) 

func main() { 
    gopath := os.Getenv("GOPATH") 
    if gopath == "" { 
     gopath = build.Default.GOPATH 
    } 
    fmt.Println(gopath) 
} 
+4

1.8 पर जाएं, GOPATH env var वैकल्पिक है। क्या होगा यदि उपयोगकर्ता के पास यह नहीं है? क्या डिफ़ॉल्ट पाने का कोई तरीका है? मुझे लगता है कि रन रनटाइम के पास गोपाथ पाने का एक तरीका होना चाहिए, जिससे आप इसे अपने लिए समझ सकें। – tothemario

+0

@ टोथमेरियो मैंने एक उत्तर पोस्ट किया कि आप गो 1.8 के बाद वैध 'GOPATH' कैसे प्राप्त कर सकते हैं। हालांकि, मैं मानता हूं कि आदर्श रूप से रनटाइम को उपयोगकर्ता के 'गोपाथ' प्राप्त करने का एक तरीका प्रदान करना चाहिए। – tmh

+1

@ टोथेमारियो ने गो 1.8 के डिफ़ॉल्ट गो पथ कार्यान्वयन से कोड का उपयोग करके उत्तर अपडेट किया। – codefreak

1

के बाद से जाओ 1.8, वहाँ है: जाओ 1.8+

जाओ 1.8 के लिए

package main 

import (
    "fmt" 
    "os" 
    ) 

func main() { 
    fmt.Println(os.Getenv("GOPATH")) 
} 

अद्यतन डिफ़ॉल्ट GOPATH जाने/निर्माण के माध्यम से निर्यात किया है एक default GOPATH:

GOPATH पर्यावरण चर आपके कार्यक्षेत्र का स्थान निर्दिष्ट करता है। यह आपके घर निर्देशिका के अंदर जाने वाली निर्देशिका में डिफ़ॉल्ट है, इसलिए यूनिक्स पर $HOME/go, योजना 9 पर $home/go, और %USERPROFILE%\go (आमतौर पर C:\Users\YourName\go) विंडोज पर।

इसका मतलब है कि GOPATH पर्यावरण चर आवश्यक रूप से किसी भी चीज़ पर सेट नहीं है।

तुम अब भी os.Getenv का उपयोग मूल्य प्राप्त कर सकते हैं, लेकिन मामले में यह सेट नहीं है आप mitchellh/go-homedir का उपयोग कर सुनिश्चित करें कि आप उदाहरण के लिए बजाय plattform विशेष डिफ़ॉल्ट मान का उपयोग, बनाने की जरूरत है:

package main 

import (
     "fmt" 
     "log" 
     "os" 

     "github.com/mitchellh/go-homedir" 
) 

func main() { 
     p, err := gopath() 
     if err != nil { 
       log.Fatalf("Error finding GOPATH: %v", err) 
     } 

     fmt.Println(p) 
} 

func gopath() (string, error) { 
     s := os.Getenv("GOPATH") 
     if s != "" { 
       return s, nil 
     } 
     return homedir.Expand("~/go") 
} 
+0

यह थोड़ा अधिक है। डिफॉल्ट जाने के लिए हम गो के अपने स्रोत कोड से कोड का उपयोग कर सकते हैं। Https://github.com/golang/go/blob/go1.8/src/go/build/build.go#L260-L277 – codefreak

+0

@codefreak देखें निश्चित रूप से सरल तरीके हैं और आपका उत्तर भी मान्य है। मुझे 'गो-होमडेर' के बारे में क्या पसंद है यह है कि जब संदेह होता है, तो यह घर निर्देशिका खोजने के कई तरीकों की कोशिश करता है, और यदि सभी विफल हो जाते हैं, तो यह वास्तव में एक त्रुटि देता है। तो इस कोड के उपयोगकर्ता एक सार्थक त्रुटि संदेश लौट सकते हैं। यदि आप बस एक खाली स्ट्रिंग वापस करते हैं, तो उपयोगकर्ताओं को यह जांचना होगा कि यह खाली है या नहीं। अगर उन्हें उपेक्षा करनी चाहिए, तो इससे कुछ किनारे के मामलों में अप्रत्याशित व्यवहार या अजीब त्रुटियां हो सकती हैं। – tmh

+0

प्रश्न का बिंदु GOPATH को ढूंढना है, घर पर नहीं। घर डीआईआर खोजने के लिए go-homedir महान है। लेकिन यदि गो स्वयं डिफ़ॉल्ट GOPATH फ़ंक्शन का उपयोग करता है, तो किनारे के मामलों की देखभाल करने का क्या मतलब है जो गो बिल्ड कोड स्वयं का ख्याल नहीं रखता है। वैसे भी चलो उपयोगकर्ताओं को यह तय करने दें कि उन्हें सबसे ज्यादा पसंद है :) – codefreak

4

आपको go/build पैकेज का उपयोग करना चाहिए।

package main 

import (
    "fmt" 
    "go/build" 
) 

func main() { 
    fmt.Println(build.Default.GOPATH) 
} 
0

मैं आज जिस चीज़ पर काम कर रहा हूं उसके लिए मैं इस पर गड़बड़ कर रहा था, और यह अपेक्षा की तुलना में अधिक परेशान था। अंत में, यह मेरे द्वारा किए गए विभिन्न परीक्षणों में (मेरे लिए 'कठोर' परीक्षण नहीं) के लिए काम करना प्रतीत होता था।

goPath := strings.Split(os.Getenv("GOPATH"), string(os.PathListSeparator)) 
if len(goPath) == 0 { 
    goPath = append(goPath, build.Default.GOPATH) 
} else if goPath[0] == "" { 
    goPath[0] = build.Default.GOPATH 
} 

ध्यान दें कि मैं केवल 1 पथ का उपयोग करने के लिए यदि अनेक पथों GOPATH पर सूचीबद्ध हैं का फैसला किया है, मैं कुछ सूचीबद्ध 1 से अधिक पथ होगा संदेह है, और पहले होगा जहां go get स्रोत डालता है (मुझे लगता है कि के रूप में)। यह कोड खाता नहीं है कि पथ मान्य हैं या नहीं।

यह भी ध्यान दें कि GOPATH प्राप्त करने के बाद फ़ाइल पथ बनाने के लिए, मुझे path/filepath.Join()path.Join() का उपयोग करना पड़ा। यदि पहले तर्क में \, और/दूसरों के लिए पूर्व में विंडोज़ का उपयोग किया जाएगा। यद्यपि खिड़कियां जाहिर तौर पर पथों को स्वीकार कर सकती हैं, मेरे सभी पाथ और गोपाथ-जैसे पर्यावरणीय चर सामान्य \ विंडोज़ के साथ लिखे गए हैं। path.Join() एक अमान्य पथ का उत्पादन/उपयोग किया जाता है।

संबंधित मुद्दे