builtin standard code package (which is a universe package). This article will explain code packages and package imports in Go.
simple-import-demo.go.)
package main
import "fmt"
func main() {
fmt.Println("Go has", 25, "keywords.")
}
simple-import-demo.go. The main entry function of a program must be put in a package named main.
fmt standard package by using the import keyword. The identifier fmt is the package name. It is also used as the import name of, and represents, this standard package in the scope of containing source file. (Import names will be explained a below section.) There are many format functions declared in this standard package for other packages to use. The Println function is one of them. It will print the string representations of an arbitrary number of arguments to the standard output.
Println function. Note that the function name is prefixed with a fmt. in the call, where fmt is the name of the package which contains the called function. The form aImportName.AnExportedIdentifier is called a qualified identifier. AnExportedIdentifier is called an unqualified identifier.
fmt.Println function call has no requirements for its arguments, so in this program, its three arguments will be deduced as values of their respective default types, string, int and string.
fmt.Println call, a space character is inserted between each two consecutive string representations and a newline character is printed at the end.
$ go run simple-import-demo.go Go has 25 keywords.
Println is an upper case letter (so the Println function is exported), which is why the Println function declared in the fmt standard package can be used in the above example program.
print and println, have similar functionalities as the corresponding functions in the fmt standard package. Built-in functions can be used without importing any packages.
print and println, are not recommended to be used in the production environment, for they are not guaranteed to stay in the future Go versions.
package main
import "fmt"
import "math/rand"
func main() {
fmt.Printf("Next pseudo-random number is %v.\n", rand.Uint32())
}
math/rand package, which is a sub-package of the math standard package. This package provides some functions to produce pseudo-random numbers.
rand is used as the import name of the imported math/rand standard package. A rand.Uint32() call will return a random uint32 integer number.
Printf is another commonly used function in the fmt standard package. A call to the Printf function must take at least one argument. The first argument of a Printf function call must be a string value, which specifies the format of the printed result. The %v in the first argument is called a format verb, it will be replaced with the string representation of the second argument. As we have learned in the article basic types and their literals, the \n in a double-quoted string literal will be escaped as a newline character.
Next pseudo-random number is 2596996162.
rand.Seed function when the program just starts.
().
package main
// Multiple packages can be imported together.
import (
"fmt"
"math/rand"
"time"
)
func main() {
// Set the random seed (only needed before Go 1.20).
rand.Seed(time.Now().UnixNano())
fmt.Printf("Next pseudo-random number is %v.\n", rand.Uint32())
}
time standard package, which provides many time related utilities.
time.Now() returns the current time, as a value of type time.Time.
UnixNano is a method of the time.Time type. The method call aTime.UnixNano() returns the number of nanoseconds elapsed since January 1, 1970 UTC to the time denoted by aTime. The return result is a value of type int64, which is also the parameter type of the rand.Seed function (note: the rand.Seed function has been deprecated since Go 1.20). Methods are special functions. We can learn methods in the article methods in Go for details later.
fmt.Printf Format Verbs
fmt.Printf call, it will be replaced with the string representation of the second argument. In fact, there can be multiple format verbs in the first string argument. The second format verb will be replaced with the string representation of the third argument, and so on.
%v, which will be replaced with the general string representation of the corresponding argument.
%T, which will be replaced with the type name or type literal of the corresponding argument.
%x, which will be replaced with the hex string representation of the corresponding argument. Note, the hex string representations for values of some kinds of types are not defined. Generally, the corresponding arguments of %x should be strings, integers, integer arrays or integer slices (arrays and slices will be explained in a later article).
%s, which will be replaced with the string representation of the corresponding argument. The corresponding argument should be a string or byte slice.
%% represents a percent sign.
package main
import "fmt"
func main() {
a, b := 123, "Go"
fmt.Printf("a == %v == 0x%x, b == %s\n", a, a, b)
fmt.Printf("type of a: %T, type of b: %T\n", a, b)
fmt.Printf("1%% 50%% 99%%\n")
}
a == 123 == 0x7b, b == Go type of a: int, type of b: string 1% 50% 99%
Printf format verbs, please read the online fmt package documentation, or view the same documentation by running a local documentation server. We can also run go doc fmt to view the documentation of the fmt standard package, and run go doc fmt.Printf to view the documentation of the fmt.Printf function, in a terminal.
internal folder name is viewed as a special package. It can only be imported by the packages in and under the direct parent directory of the internal folder. For example, package .../a/b/c/internal/d/e/f and .../a/b/c/internal can only be imported by the packages whose import paths have a .../a/b/c prefix.
a depends on package b and package b depends on package c, then source files in package c can't import package a and b, and source files in package b can't import package a.
main and containing main entry functions as program packages (or command packages), and call other packages as library packages. Program packages are not importable. Each Go program should contain one and only one program package.
main.
init Functions
init declared in a package, even in a source code file. The functions named as init must neither have any input parameters nor return results.
init identifier can only be used in function declarations. We can't declare package-level variable/constants/types which names are init.
init function will be (sequentially) invoked once and only once (before invoking the main entry function). So the meaning of the init functions are much like the static initializer blocks in Java.
init functions:
package main
import "fmt"
func init() {
fmt.Println("hi,", bob)
}
func main() {
fmt.Println("bye")
}
func init() {
fmt.Println("hello,", smith)
}
func titledName(who string) string {
return "Mr. " + who
}
var bob, smith = titledName("Bob"), titledName("Smith")
hi, Mr. Bob hello, Mr. Smith bye
init functions in all involved packages in a program will be invoked sequentially. An init function in an importing package will be invoked after all the init functions declared in the dependency packages of the importing package for sure. All init functions will be invoked before invoking the main entry function.
init functions in the same source file is from top to bottom. Go specification recommends, but doesn't require, to invoke the init functions in different source files of the same package by the alphabetical order of filenames of their containing source files. So it is not a good idea to have dependency relations between two init functions in two different source files.
init function declared in the same package is invoked.
y, z, x, and w.
func f() int {
return z + y
}
func g() int {
return y/2
}
var (
w = x
x, y, z = f(), 123, g()
)
import importname "path/to/package"
importname is optional, its default value is the name (not the folder name) of the imported package.
importname portions are all omitted, for they are identical to the respective package names. These import declarations are equivalent to the following ones:
import fmt "fmt" // <=> import "fmt"
import rand "math/rand" // <=> import "math/rand"
import time "time" // <=> import "time"
importname portion presents in an import declaration, then the prefix tokens used in qualified identifiers must be importname instead of the name of the imported package.
importname for at least one package in the two.
package main
import (
format "fmt"
random "math/rand"
"time"
)
func main() {
random.Seed(time.Now().UnixNano())
format.Print("A random number: ", random.Uint32(), "\n")
// The following line fails to compile,
// for "rand" is not identified.
/*
fmt.Print("A random number: ", rand.Uint32(), "\n")
*/
}
format and random as the prefix token in qualified identifiers, instead of the real package names fmt and rand.
Print is another function in the fmt standard package. Like Println function calls, a Print function call can take an arbitrary number of arguments. It will print the string representations of the passed arguments, one by one. If two consecutive arguments are both not string values, then a space character will be automatically inserted between them in the print result.
importname in the full form import declaration can be a dot (.). Such imports are called dot imports. To use the exported elements in the packages being dot imported, the prefix part in qualified identifiers must be omitted.
package main
import (
. "fmt"
. "time"
)
func main() {
Println("Current time:", Now())
}
Println instead of fmt.Println, and Now instead of time.Now must be used.
importname in the full form import declaration can be the blank identifier (_). Such imports are called anonymous imports (some articles elsewhere also call them blank imports). The importing source files can't use the exported code elements in anonymously imported packages. The purpose of anonymous imports is to initialize the imported packages (each of init functions in the anonymously imported packages will be called once).
init functions declared in the net/http/pprof standard package will be called before the main entry function is called.
package main
import _ "net/http/pprof"
func main() {
... // do some things
}
package main
import (
"net/http" // error: imported and not used
. "time" // error: imported and not used
)
import (
format "fmt" // okay: it is used once below
_ "math/rand" // okay: it is not required to be used
)
func main() {
format.Println() // use the imported "fmt" package
}
The Go 101 project is hosted on Github. Welcome to improve Go 101 articles by submitting corrections for all kinds of mistakes, such as typos, grammar errors, wording inaccuracies, description flaws, code bugs and broken links.
If you would like to learn some Go details and facts every serveral days, please follow Go 101's official Twitter account @zigo_101.
reflect standard package.sync standard package.sync/atomic standard package.