【问题标题】:How to import my own function defined out of main package in Go?如何导入我自己在 Go 的主包中定义的函数?
【发布时间】:2016-04-30 06:32:14
【问题描述】:

我是 Go 的新手,但我来自 C++ 学校。我只想做一个项目,把逻辑拆分成多个文件。

在 C++ 中,我只需要在我的 main_file.cpp 上添加一个

#include "my_own_lib.hpp" 

(类似于 Node.js 中的 module.exportsrequire('relative/path/to/my-own-lib')

就是这样。在 Go 中,我遵循相同的逻辑,但结果是:

$ go run main.go
main.go:4:8: open /Users/mt/Documents/Codes/go/src/github.com/mt/Apollo/tst: no such file or directory

我的文件:

ma​​in.go

package main

import "fmt"
import "./tst"

func main() {
    fmt.Println("just testing")
    tst.p()
}

tst.go

package tst

import "fmt"

func p() {
    fmt.Println("ola")
}

当然我的文件结构是:

myFolder/
   |- main.go
   |_ tst.go

谁能告诉我这样做的正确方法是什么?

【问题讨论】:

  • 请务必阅读有关包如何在 go 中工作的信息。例如:golang.org/doc/code.html。包始终位于具有包名的文件夹中。在您的示例中, tst.go 应该位于名为 tst 的文件夹中
  • 另外,当使用“go run”时,您必须指定所有要编译和运行的文件。 Includes 仅在您的 gopath 中查找包。在这种情况下,您可能想要执行“go run *.go”来实际运行这两个文件。你只在不同的“包”中导入东西,这也将在与你的“包主”代码不同的目录中

标签: go import


【解决方案1】:

如果你也将 tst.go 的包设置为“package main”,你将能够在没有任何 import 语句的情况下访问 p()。

$ cat main.go 
package main

func main() {
    p()
}
$ cat tst.go 
package main

import "fmt"

func p() {
    fmt.Println("ola")
}
$ go build ./ && ./test 
ola

我相信这会满足您的要求:

我只是想做一个项目,把逻辑拆分成很多不同的文件。

如果您正在构建程序而不是库,则公认的 Go 约定是将所有文件都作为“主包”:

包“main”告诉 Go 编译器该包应该编译为可执行程序而不是共享库。 http://thenewstack.io/understanding-golang-packages/

请解释你的反对意见

这里有一些众所周知的 Go 惯用项目的例子,它们完全按照我说的做:

这些是代码拆分在多个 Go 文件中的可执行文件,所有这些文件都属于“package main”。

由于OP有点不清楚,您可以选择解释他要创建一个外部包,tst。但他说的很清楚:

我只是想做一个项目,把逻辑拆分成很多不同的文件。

他说很多文件 - 不是很多外部包。他还说:

当然我的文件结构是:

myFolder/
   |- main.go
   |_ tst.go

我的建议是在这种情况下做事的正确方法:

executable/
   |- main.go (package main)
   |- a.go (package main)
   |- b.go (package main)

随着应用程序在 main、a 和 b 之间拆分。

【讨论】:

  • 当然,我正在尝试使用 gin (gin-gonic.github.io/gin) 构建 API-REST,并遵循 express(node js) 用户定义的模式。 routesfolder 上的路由,controllersfolder 上的控制器等等。
  • 另一方面,我已经制作了'go run *.go'并且输出是预期的,但主要思想只是运行我的主文件main.go或在杜松子酒框架中运行我的app.js
  • 尝试将 tst.go 的包更改为“package main”,然后执行“go build ./”以创建可执行文件并运行该可执行文件。
  • 外部包不是“主包”,它们有自己的包名。 Main 是为可执行文件保留的。
  • 是的。但他并没有尝试制作外部包装。他正在尝试制作一个项目,将其拆分为多个文件。
【解决方案2】:

如果我没看错:

导入路径应该是完整路径,在 $GOPATH 之后,因此可能是 'github.com/mt/Apollo/tst'

这是包代码应该驻留的位置,也是包导入路径。从文档中查看:

标准库中的包都有短路径,例如 “fmt”和“net/http”。对于您自己的包裹,您必须选择一个基地 不太可能与标准的未来添加内容发生冲突的路径 库或其他外部库。

如果您将代码保存在某个源代码库中,那么您 应该使用该源存储库的根作为您的基本路径。为了 例如,如果你在 github.com/user 上有一个 GitHub 帐户,那应该 成为你的基本路径。

我有它的工作。这正是我所做的:

main.go

package main

import (
    "fmt"
    "github.com/mt/Apollo/tst"
)

func main() {
    fmt.Println("just testing")
    tst.P()
}

tst.go

package tst

import (
    "fmt"
)

func P() {
    fmt.Println("ola")
}

目录结构如下:

mt/Apollo/main.go

mt/Apollo/tst/tst.go

另外需要注意的是,我在 func p() 中将“P”大写。不导出小写标识符。更多关于here

【讨论】:

  • 我已按照您的提示进行操作,但输出不是预期的:/
  • /Users/mt/Documents/Codes/go/src/github.com/mt/Apollo/tst存在吗?
  • 当然存在 rout,Apollo 是我的项目文件夹,tst 是 .gofile
  • @Chelo Tavano 查看golang.org/doc/code.html#Workspacesgolang.org/doc/code.html#PackagePaths。您的包源代码应位于具有包名的目录中,然后您的导入路径将包含完整的目录路径。
  • @CheloTavano 在我的回答中查看编辑,看看是否有帮助
猜你喜欢
  • 2019-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 1970-01-01
  • 2018-05-28
相关资源
最近更新 更多