2014-06-20 122 views
10

我試圖理解軟件包如何在golang的實際執行中取得更好的效果,而不是通常做的或被認爲是好的做法(我們也可以在後面討論好的做法,但是我希望瞭解去首先)。軟件包如何在golang中工作

effective go它說:

「另一個約定是包名是它的源目錄的基本名稱......」

然而,上面的描述似乎並不被強迫或被強制要求。因此,我想知道,如果允許我有多個文件與不同包裝聲明在頂部相同目錄基地。如果允許我在同一個目錄中有多個包聲明,那麼如何導入它們並在同一個文件中分別使用它們?基本上,我想我遇到的一個問題是由於一些go tutorial/documentation的措辭。如果是按照慣例,那麼對我而言,它暗示它不是由語言執行的。因爲例如,程序員不要按照慣例爲函數編寫關鍵字func。我們寫func因爲否則會去喊你,它會不編譯。因此,我希望用下面的例子來說明這一點(如果可能的話,更改文檔以便繼續下去,因爲在我看來這是一個大問題,這怎麼能做到呢?)。

例如說我有三個文件A.goB.goC.go分別打印打印功能Print()簡單地打印,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 
} 

或者我們甚至不需要指定名稱,如果包裝statments是前已經不同:

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 /基地和名稱C.go 包//文件Cpkg

import "fmt" 

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

另外,如果你可以從base有一個名字不同 ,有人可以向我澄清進口是如何實際完成的?如果包裝名稱爲package Apkg,則以進口產品爲準:import github.com/user_me/baseimport github.com/user_me/base/Apkggithub.com/user_me/Apkg

我還沒有測試過,但我很快就會這麼做。進口交易對我來說有點令人困惑,並希望得到答案並與全世界分享。

回答

7

不,這是每個文件夾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" 
) 

或者你的庫被稱爲主:

此外,您還可以在導入重命名的包,例如

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

所以它不是好「公約」時,語言強制執行它? –

+0

是的,例如檢查更新 – OneOfOne

+0

有趣的是,他們用這樣一種奇怪的方式來表達它的「約定」,如果該語言強制執行它的話。我對此持懷疑態度和困惑的原因是因爲以前,我在'base'的文件頂部有一個包名稱,它與基本目錄名稱不匹配。例如,我有'package superBase'而不是'package base',我仍然能夠運行'go test',即使我的導入是'import baseName github.com/user_me/base',但是每個文件的包是'包superBase'。奇怪的。這是關於'去測試'的特別事情嗎? –

相關問題