在同一个目录中放置两个包是否有意义?

huangapple go评论164阅读模式
英文:

Does it make sense to have two packages in the same directory?

问题

我有一个项目,提供一个库(导出一些函数),同时还必须提供一个命令行界面(必须有一个可执行文件)。

目录结构示例:

whatever.io/
    myproject/
        main.go
        myproject.go

Go编译器需要package mainfunc main来启动执行。我的库需要package myproject,我把东西放在里面。当我正在构建另一个尝试导入myproject的项目时,go工具会显示以下信息:

main.go:5:2: 在$GOPATH/src/whatever.io/myproject中找到了myproject(myproject.go)和main(main.go)两个包

所以我认为没有办法做到这一点。

我应该将库或CLI移动到另一个包中吗?

英文:

I have a project that provides a library (exports some funcs) and also must provide a command-line interface (there must be an executable file).

Example of directory structure:

whatever.io/
    myproject/
        main.go
        myproject.go

The go compiler needs the package main and func main to start execution. My library needs the package myproject where I put stuff on it. This is what the go tool says when I am building another project that tries to import myproject:

main.go:5:2: found packages myproject (myproject.go) and main (main.go) in $GOPATH/src/whatever.io/myproject

So I believe there is no way to do it.

Should I move the library or the CLI to another package?

答案1

得分: 36

只需将您的包移动到与main.go相同的目录中的新文件夹中。
请记住从$GOPATH的引用中导入新的包。

示例:

user@user:~/p/go/test/so-multipack$ ls -R
.:
a  main.go

./a:
a.go
user@user:~/p/go/test/so-multipack$ cat main.go 
package main

import (
    "../so-multipack/a"
)
func main(){
    a.Hello()
}
user@user:~/p/go/test/so-multipack$ cat a/a.go 
package a
import (
    "fmt"
)
func Hello(){
    fmt.Println("hello from a")
}
user@user:~/p/go/test/so-multipack$ go run main.go 
hello from a
user@user:~/p/go/test/so-multipack$ go build 
user@user:~/p/go/test/so-multipack$ ls
a  main.go  so-multipack
user@user:~/p/go/test/so-multipack$ 

有用的链接:

https://stackoverflow.com/questions/19234445/go-build-vs-go-build-file-go/19240125#19240125

英文:

Just move your packages inside a new folder within the same directory of main.go.
Remember to import the new package from the reference of the $GOPATH.

Example:

user@user:~/p/go/test/so-multipack$ ls -R
.:
a  main.go

./a:
a.go
user@user:~/p/go/test/so-multipack$ cat main.go 
package main

import (
    "../so-multipack/a"
)
func main(){
    a.Hello()
}
user@user:~/p/go/test/so-multipack$ cat a/a.go 
package a
import (
    "fmt"
)
func Hello(){
    fmt.Println("hello from a")
}
user@user:~/p/go/test/so-multipack$ go run main.go 
hello from a
user@user:~/p/go/test/so-multipack$ go build 
user@user:~/p/go/test/so-multipack$ ls
a  main.go  so-multipack
user@user:~/p/go/test/so-multipack$ 

Useful link:

https://stackoverflow.com/questions/19234445/go-build-vs-go-build-file-go/19240125#19240125

答案2

得分: 31

你不能在同一个目录下拥有两个包,因此会出现错误。所以,根据 @Larry Battle 的建议,解决方案是将你的 myproject.go 移动到一个新的目录中。

根据如何编写 Go 代码

Go 代码必须保存在一个工作区内。工作区是一个目录层次结构,其根目录下有三个目录:

src 目录包含按包组织的 Go 源文件(每个目录一个包),

pkg 目录包含包对象,

bin 目录包含可执行命令。

英文:

You cannot have two packages per directory, hence the error. So the solution as @Larry Battle said to move your myproject.go to a new directory.

From How to write go code

> Go code must be kept inside a workspace. A workspace is a directory
> hierarchy with three directories at its root:
>
> src contains Go source files organized into packages (one package per directory),
>
> pkg contains package objects, and
>
> bin contains executable commands.

答案3

得分: 17

在大多数情况下,不需要。然而,对于单元测试有一个例外情况。

工作示例:

在一个目录(mypackage)中有两个不同的包(mypackagemypackage_test)。编译器不会对此报错。

mypackage文件夹:

mypackage/
  foo.go
  foo_test.go

mypackage/foo.go:

package mypackage

func Add(a int, b int) int {
    return a + b
}

mypackage/foo_test.go:

package mypackage_test

// 单元测试...

规则:

  1. 这两个包必须具有以下名称:

    • 目录的名称。
    • 目录的名称 + _test
  2. _test 包中的文件名称必须以 _test.go 结尾。

如果你收到类似于 found packages "foo" and "bar" 的令人困惑的编译器错误,那么你可能违反了其中一个或多个规则。

英文:

In most cases, no. However, there is an exception for unit tests.

Working Example:

Here are 2 different packages (mypackage and mypackage_test) in 1 directory (mypackage). The compiler will not complain about this.

mypackage folder:

mypackage/
  foo.go
  foo_test.go

mypackage/foo.go:

package mypackage

func Add(a int, b int) int {
    return a + b
}

mypackage/foo_test.go:

package mypackage_test

// Unit tests...

Rules:

  1. The 2 packages must have the following names:
  • NameOfDirectory.
  • NameOfDirectory + _test.
  1. The names of the files in the _test package must end with _test.go

If you're receiving a confusing compiler error along the lines of found packages "foo" and "bar", you've probably broken one or more of these rules.

答案4

得分: 8

你不能在同一个目录中有两个带有不同包名的golang文件。所以你需要将main.go移出myproject目录。

移动前的目录结构如下:

whatever.io/
    go.mod
    myproject/
        main.go
        myproject.go

移动后的目录结构如下:

whatever.io/
    go.mod
    main.go
    myproject/
        myproject.go

你还需要修改main.go的导入路径。如果模块名为aaa,修改前的代码如下:

import "aaa"

修改后的代码应该是:

import "aaa/myproject"
英文:

You can't have two golang files in one directory with two packages. So you need to move main.go out of myproject.

the directory structure before move

whatever.io/
    go.mod
    myproject/
        main.go
        myproject.go

After move

whatever.io/
    go.mod
    main.go
    myproject/
        myproject.go

And you need to change your main.go's import path. If the module name is aaa

Before

import "aaa"

Need change to this

import "aaa/myproject"

huangapple
  • 本文由 发表于 2013年12月6日 23:40:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/20427890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定