看看这个实验.

~/go/src$ tree -F
.
├── 1-foodir/
│   └── 2-foofile.go
└── demo.go

1 directory, 2 files

~/go/src$ cat demo.go 
package main

import (
    "fmt"
    "1-foodir"
)

func main() {
    fmt.Println(foopkg.FooFunc())
}

~/go/src$ cat 1-foodir/2-foofile.go 
package foopkg

func FooFunc() string {
    return "FooFunc"
}

~/go/src$ GOPATH=~/go go run demo.go 
FooFunc

我以为我们总是导入一个包名.但是上面的例子

对于像我这样来自Java和Python世界的初学者来说,这让人困惑,

为什么我们使用import语句的方式与使用import语句的方式不同 在围棋中,指的是包中定义的名字吗?你能解释一下规则吗? 在这些关于围棋的事情背后?

推荐答案

如果你说的是真的,那么你的函数调用实际上是1-foodir.FooFunc()而不是foopkg.FooFunc().相反,go会在2-foo文件中看到包名.go并将其作为foopkg导入,因为在go中,包的名称正好位于文件顶部的单词package之后.go文件,前提是它是有效的标识符.

目录的唯一用途是收集一组共享相同包名的文件.这一点在the spec篇文章中得到了重申

共享相同PackageName的一组文件构成了包的实现.实现可能要求包的所有源文件驻留在同一目录中.

在Go中,目录与包名称匹配是惯例,但不一定是这样,通常第三方包也不是这样.stdlib确实很好地遵守了这个约定.

现在,目录do发挥作用的是导入路径.在一个二进制文件中可以有两个名为"foo"的包,只要它们有different个导入路径,即.

/some/path/1/foo/some/path/2/foo

我们可以变得非常时髦,把进口商品伪装成我们想要的东西,比如我可以做的

import (
    bar "/some/path/1/foo"
    baz "/some/path/2/foo"
)

同样,这种方法有效的原因不是因为包名必须是唯一的,而是包导入路径必须是唯一的.

从这句话中可以得到的另一点启示是——在一个目录中,不能有两个包名.go编译器将抛出一个错误,指出它为cannot load package,而它为found packages foo (foo.go) and bar (bar.go).

有关详细信息,请参见https://golang.org/doc/code.html#PackageNames.

Go相关问答推荐

CGO Linux到Windows交叉编译中的未知类型名称

如何使用中间件更改http请求的响应代码?

文件路径.Abs()未在结果中提供子目录

如何根据中间件的请求设置上下文值?获取 go-staticcheck 问题

如何使用 html/template 在 golang 中运行一个范围内的范围

我无法使用反向代理更改主机标头

Go 中如何调用测试函数?

如果值为 false,gRPC 不返回布尔值

Go 信号处理程序不处理终端窗口关闭

go-libp2p - 从流中接收字节

使用go doc命令查看示例函数?

使用 oklog/run 来自 Go 编译器的错误(无值)用作值

具有近似约束的函数值导致的实例化失败

在 Go 中将指针传递给函数的正确方法是什么,以便我可以读取和/或修改指针表示的值?

go 堆栈跟踪:在某些函数调用参数或返回值之后的问题(?)标记是什么意思?

将 Simple Go Web 应用程序部署到 Elastic Beanstalk

有没有办法在一个 goroutine 返回后延迟后取消上下文?

如何使用 httputil.ReverseProxy 设置 X-Forwarded-For

Go generics:我会在哪里使用 any 而不是 interface{}?

Golang LinkedList 删除第一个元素