我尝试了解如何使用“内部”包来组织代码。让我展示一下我的结构:
project/
internal/
foo/
foo.go # package foo
bar/
bar.go # package bar
main.go
# here is the code from main.go
package main
import (
"project/internal/foo"
"project/internal/bar"
)
project/
在GOPATH树之外。无论我尝试从main.go
导入的任何路径都没有效果,唯一正常工作的案例是import "./internal/foo|bar"
。我认为我做错了什么或者一般来说“内部”包装的想法是错误的。请问有人能让事情更清楚吗?
UPDATE
上面的例子是正确的,我唯一需要的是在project/
下放置$GOPATH/src
文件夹。因此,如果我们只从project/internal/foo|bar
子树而不是从外部导入它,那么就像project/
这样的导入路径是可行的。
包裹必须位于您的$GOPATH
才能进口。你用import "./internal/foo|bar"
给出的例子是有效的,因为它进行了本地导入。 internal
只使得不与internal
目录共享根目录的代码无法导入internal
中的包。
如果你把所有这些放在你的gopath然后尝试从OuterFolder/project2/main.go
不同的位置导入OuterFolder
包含project
和project2
然后import "../../project/internal/foo"
将失败。由于不满足这个条件,它也会因为import "foo"
或你试过的任何其他方式而失败;
如果导入代码位于以“internal”目录的父级为根的树之外,则不允许导入包含元素“internal”的路径。
现在,如果你有路径$GOPATH/src/project
然后你可以从import "foo"
内做import "bar"
和$GOPATH/src/project/main.go
,导入将成功。然而,project
下面没有包含的东西将无法导入foo
或bar
。
以下方式更具可扩展性,尤其是当您计划构建多个二进制文件时
github.com/servi-io/api
├── cmd/
│ ├── servi/
│ │ ├── cmdupdate/
│ │ ├── cmdquery/
│ │ └── main.go
│ └── servid/
│ ├── routes/
│ │ └── handlers/
│ ├── tests/
│ └── main.go
├── internal/
│ ├── attachments/
│ ├── locations/
│ ├── orders/
│ │ ├── customers/
│ │ ├── items/
│ │ ├── tags/
│ │ └── orders.go
│ ├── registrations/
│ └── platform/
│ ├── crypto/
│ ├── mongo/
│ └── json/
cmd/
中的文件夹表示您要构建的二进制文件的数量。
还要检查:当你使用外部导入的对象类型时:确保你在前面加上他们所在的命名空间。作为一个golang新手,我不知道我必须这样做,并且想知道为什么VS代码只是在我保存时删除了我的导入(因为没有被使用)。这是因为我必须在导入的对象前面添加命名空间名称:
Example:
import (
"myInternalPackageName" // works fine as long as you follow all instructions in this thread
)
//Usage in code:
myInternalPackageName.TheStructName // prefix it, or it won't work.
如果你没有在对象/结构名称之前放置名称空间前缀,VS代码只是删除你的导入未被使用,然后你仍然有错误:“找不到TheStructName”...这非常令人困惑,并且我必须通过命令行在没有VS代码的情况下进行构建才能理解这一点。
关键是:我必须在实际使用该内部包中的结构时指定包前缀。
如果您不想在使用导入的对象时使用限定符前缀,请使用:
import . "thePath" // Can use contents without prefixing.
参考:What does the '.' (dot or period) in a Go import statement do?