2017-08-26 21 views
-2

我正在開發一個go包,它有點複雜,因此我想將源代碼組織到多個目錄中。我可以在多個源目錄中開發一個go包嗎?

但是,我不希望包的用戶必須使用太長的導入。無論如何,包裹的內部結構並不是他們關心的問題。

因此,我的包結構如下這樣:

subDir1 
    subSubDir1 
    subSubDir2 
subDir2 
    subSubDir3 

...等等。他們都有他們的導出電話。

我想避免,我的用戶可以導入

import (
    "mypackage/subDir1" 
    "mypackage/subDir1/subSubDir2" 
) 

...等等。

我只想要,如果他們想要使用我的軟件包中的導出函數,他們應該通過簡單地導入mypackage來訪問所有這些函數。

我試過我在.go文件中聲明瞭package mypackage。因此,我有不同目錄中的源文件,但具有相同的包聲明。

在這種情況下,我遇到的問題是我根本無法從同一個包中導入多個目錄。它說:

./src1.go:6:15: error: redefinition of ‘mypackage’ 
    "mypackage/mysubdir1" 
      ^
./src1.go:4:10: note: previous definition of ‘mypackage’ was here 
    "mypackage" 
     ^
./src1.go:5:15: error: redefinition of ‘mypackage’ 
    "mypackage/mysubdir2" 
      ^
./src1.go:4:10: note: previous definition of ‘mypackage’ was here 
    "mypackage" 
     ^

是不是有可能?

回答

2

在任何情況下都不應該這樣做,因爲語言規範允許編譯器實現拒絕這樣的結構。從Spec: Package clause:引用

一組共享相同PackageName的文件形成一個包的實現。 實施可能要求包的所有源文件都位於同一個目錄中。

改爲「結構化」您的文件名以模仿文件夾結構;例如而不是

foo/foo1.go 
foo/bar/bar1.go 
foo/bar/bar2.go 

文件,您可以簡單地使用:

foo/foo1.go 
foo/bar-bar1.go 
foo/bar-bar2.go 

此外,如果你的包是如此之大,你會需要多個文件夾,甚至是「主機」的包實施的文件,你應該真的考慮不把它作爲一個單獨的包來實現,而是把它分解成多個包。

另請注意Go 1.5介紹internal packages。如果您在包文件夾內創建了一個特殊的internal子文件夾,則可以在其中創建任意數量的子包(即使使用多個級別)。你的軟件包將能夠導入和使用它們(或者更精確地說,所有的軟件包都植於你的軟件包文件夾中),但是除此之外別的軟件都無法做到這一點,這是編譯時錯誤。

例如您可以創建一個foo包,具有一個foo/foo.go文件和foo/internal/bar包。 foo將能夠導入foo/internal/bar,但例如boo不會。另外foo/baz也將能夠導入並使用foo/internal/bar,因爲它的根源是foo/

因此,您可以使用內部軟件包將您的大包分解爲較小的包,從而將您的源文件有效地分組到多個文件夾中。唯一需要注意的是將你的軟件包想要導出的所有東西放入軟件包中,而不是放入內部軟件包中(因爲那些軟件不能從「外部」導入/顯示)。

-1

在你的包源代碼中,你必須區分你的源目錄重命名導入。您可以在所有源文件中聲明相同的package mypackage(即使它們位於不同的目錄中)。

但是,當您導入它們時,您應該爲目錄提供個人名稱。在源src1.go,導入其他目錄上這樣說:

import (
    "mypackage" 
    submodule1 "mypackage/mySubDir" 
) 

而你,也就能夠達到「mypackage的」定義爲mypackage.AnyThing()的API,並在mySubDir定義爲submodule1.AnyThing()的API。

外部世界(即您的軟件包的用戶)將看到myPackage.AnyThing()中的所有導出實體。

避免命名空間衝突。並且像例子中那樣使用更好的可理解的,直觀的命名。

0

是的,這是可行的,沒有任何問題,只需手動調用Go編譯器,這不是通過go工具。

但最好的建議是:不要這樣做。這是醜陋的,不必要的複雜。只需正確設計您的包裝。

相關問題