2014-06-20 120 views
10

我试图理解软件包如何在golang的实际执行中取得更好的效果,而不是通常做的或被认为是好的做法(我们也可以在后面讨论好的做法,但是我希望了解去首先)。软件包如何在golang中工作

effective go它说:

“另一个约定是包名是它的源目录的基本名称......”

然而,上面的描述似乎并不被强迫或被强制要求。因此,我想知道,如果允许我有多个文件与不同包装声明在顶部相同目录基地。如果允许我在同一个目录中有多个包声明,那么如何导入它们并在同一个文件中分别使用它们?基本上,我想我遇到的一个问题是由于一些go tutorial/documentation的措辞。如果是按照惯例,那么对我而言,它暗示它不是由语言执行的。因为例如,程序员不要按照惯例为函数编写关键字func。我们写func因为否则会去喊你,它会不编译。因此,我希望用下面的例子来说明这一点(如果可能的话,更改文档以便继续下去,因为在我看来这是一个大问题,这怎么能做到呢?)。

例如说我有三个文件A.goB.goC.go分别打印打印功能Print()简单地打印,B,C。它们全都位于相同的基本目录,可能为base。然后每个都有不同的包装声明package Apkg, package Bpkg, package Cpkg

你会怎么去导入它们?会有如下工作?

package main 

import(
    nameA "github.com/user_me/base/Apkg" 
    nameB "github.com/user_me/base/Bpkg" 
    nameC "github.com/user_me/base/Cpkg" 
) 

func main() { 
    nameA.Print() \\prints a 
    nameB.Print() \\prints b 
    nameC.Print() \\prints c 
} 

或者我们甚至不需要指定名称,如果包装statments是前已经不同:

package main 

import(
    "github.com/user_me/base" 
) 

func main() { 
    Apkg.Print() \\prints a 
    Bpkg.Print() \\prints b 
    Cpkg.Print() \\prints c 
} 

打印的文件是:

A.go:

//file at github.com.user_me/base and name A.go 
package Apkg 

import "fmt" 

func Print(){ 
    fmt.Println("A") 
} 

B.go:

//file at github.com.user_me/base and name B.go 
package Bpkg 

import "fmt" 

func Print(){ 
    fmt.Println("B") 
} 

C.go: 在github.com.user_me /基地和名称C.go 包//文件Cpkg

import "fmt" 

func Print(){ 
    fmt.Println("C") 
} 

另外,如果你可以从base有一个名字不同 ,有人可以向我澄清进口是如何实际完成的?如果包装名称为package Apkg,则以进口产品为准:import github.com/user_me/baseimport github.com/user_me/base/Apkggithub.com/user_me/Apkg

我还没有测试过,但我很快就会这么做。进口交易对我来说有点令人困惑,并希望得到答案并与全世界分享。

回答

7

不,这是每个文件夹1包,所以你必须让他们:

$GOPATH/src/github.com/user_me/base/Apkg/a.go 
$GOPATH/src/github.com/user_me/base/Bpkg/b.go 
$GOPATH/src/github.com/user_me/base/Cpkg/c.go 

你甚至不能以其他方式构建它:

┌─ [email protected] [/t/blah]                           
└──➜ go build 
can't load package: package .: found packages pkgA (blah1.go) and pkgB (blah2.go) in /tmp/blah 

你的你的包名称不需要与它们所在的目录具有相同的名称,但是一个目录中的所有文件必须具有相同的包名称。 (顺便说一句坏主意)

import (
    cr "crypto/rand" 
    mr "math/rand" 
) 

或者你的库被称为主:

此外,您还可以在导入重命名的包,例如

import m "github.com/user_me/base/main" 
+0

所以它不是好“公约”时,语言强制执行它? –

+0

是的,例如检查更新 – OneOfOne

+0

有趣的是,他们用这样一种奇怪的方式来表达它的“约定”,如果该语言强制执行它的话。我对此持怀疑态度和困惑的原因是因为以前,我在'base'的文件顶部有一个包名称,它与基本目录名称不匹配。例如,我有'package superBase'而不是'package base',我仍然能够运行'go test',即使我的导入是'import baseName github.com/user_me/base',但是每个文件的包是'包superBase'。奇怪的。这是关于'去测试'的特别事情吗? –

相关问题