Packages - Introduction
Every Go program is made up of packages.
Note: Do not get confused with Go modules, which is Go’s dependency management system. A Go modules usually contains one or more Go packages. We will discuss Go modules later, for now, just remember that we are talking about packages and just pretend modules don’t exist.
Programs start running in package main.
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("My favorite number is", rand.Intn(10))
}
Use package at the beginning of the code to specify the current package.
Use import to import other packages.
Import
import can take the following two styles:
import (
"fmt"
"math/rand"
)
代码语言:javascript复制import "fmt"
import "math/rand"
The prior grouped style is the recommeded “good” style by Go.
Exported names and non-exported names
In Go packages, only exported names can be accessed outside the same package.
A name is exported if it begins with a capital letter.
Examples:
Pizzais an exported name since it starts with capital letterPPistarts with a capital letter thus is an exported name from packagemath. (Accessible withmath.Pi)Printlnis an exported name of packagefmtFoobarwill be an exported name if you ever use it in your package.foobarhowever, will NOT be exported if you use it in your package. It’ll be “unexported” thus inaccessable from outside the package.
By designing the language this way, Go effectively forced you to name your functions and types using a standard and preselected naming style. (“CamelCase” for exported names, “lower camelCase” for internal unexported names)
Whether that’s a good thing or a bad thing is up for debate, but this design decision ditched the need of the keyword
public,exportorexterncommonly found in other languages, making programmers’ lives easier. It also makes the naming in all packages more unified and predictable, which is a good thing.
Package Scope
There’s no “global” scope in Go, instead, all functions and variables that is not local is in the package scope.
代码语言:javascript复制package myPackage
var v1, v2, v3 int // in package scope 'myPackage'
var Var1 int // in package scope 'myPackage', exported
func myfunction() int {} // also in package scope 'myPackage'
func AnotherFunc() int {} // in package scope 'myPackage', but it's also "exported" so
// it is accessible outside of package 'myPackage' by using
// `myPackage.AnotherFunc()`
Functions and variables within package scope is accessible within the whole package. Whether a name is accessible from outside the package however, is determined by the naming style of the name. See Exported names and non-exported names.
In this case, AnotherFunc() can be accessed in another package like this:
package main
import (
"fmt"
"path/to/myPackage" // we will talk about this later
)
func main() {
myPackage.AnotherFunc() // works
fmt.Println(myPackage.Var1) // works
// myPackage.myFunction() // this doesn't work since `myFunction` is not exported
}
This is just for showcasing the difference between exported names and non-exported names, as well as the idea that you can access functions and variables in other packages.
Conclusion
We’ll be covering more about packages in a future article. For now, knowing how to use packages is enough.


