Golang packages: Difference between revisions
From wikinotes
(14 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
<blockquote> | <blockquote> | ||
* Packages are groups of related code. | * Packages are groups of related code. | ||
* | * Functions from files belonging to same package can be called as if from same file (no prefix) | ||
* | * Otherwise, exported functions are callable when a package is imported (and use the packagename as a prefix) | ||
* Unless this is a library, the <code>main</code> package is your program's entrypoint (ex. cli). It must have exactly one <code>main()</code> function. | |||
* Exported symbols in the <code>main</code> package are not accessible in subpackages | |||
</blockquote><!-- Basics --> | </blockquote><!-- Basics --> | ||
Line 14: | Line 17: | ||
"fmt" // builtin pkgs have no module-path prefix | "fmt" // builtin pkgs have no module-path prefix | ||
"golang.org/x/example/stringutil" // non-builtin pkgs have module-path prefix (incl. local sub-packages) | "golang.org/x/example/stringutil" // non-builtin pkgs have module-path prefix (incl. local sub-packages) | ||
foo "golang.org/x/example/bar" // import 'bar' package, as name 'foo' | |||
. "golang.org/x/example/test" // import test, merged into local namespace | |||
) | ) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 77: | Line 83: | ||
</blockquote><!-- Anatomy --> | </blockquote><!-- Anatomy --> | ||
== | == Scope == | ||
<blockquote> | <blockquote> | ||
Only exported symbols are exposed when a package is imported. | Only exported symbols are exposed when a package is imported. | ||
* Exported | * Exported functions/types/variables are upper-cased. | ||
* If a symbol is not exported, it is only accessible internally within the same package. not even in sub-packages. | |||
* Exported functions within internal packages are only available within that package. | |||
</blockquote><!-- | </blockquote><!-- Scope --> | ||
== | == Package Init == | ||
<blockquote> | <blockquote> | ||
Each file within a package can define an <code>init</code> function.<br> | Each file within a package can define an <code>init</code> function.<br> | ||
Line 94: | Line 99: | ||
<syntaxhighlight lang="go"> | <syntaxhighlight lang="go"> | ||
// names/name.go | |||
import "fmt" | import "fmt" | ||
Line 104: | Line 109: | ||
func init() { | func init() { | ||
name = "foo" | name = "foo" | ||
fmt.Println( | fmt.Println("imported the first time") | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</blockquote><!-- init function --> | </blockquote><!-- init function --> | ||
== Internal Packages == | |||
<blockquote> | |||
Packages defined within the <code>internal/</code> directory can export symbols for internal use, but it will not be publicly available outside of the module. | |||
<syntaxhighlight lang="bash"> | |||
mygolib/ | |||
go.mod | |||
main.go | |||
publiclib/ | |||
format.go | |||
internal/ | |||
logger/ | |||
logger.go | |||
maths/ | |||
division.go | |||
multiplication.go | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="go"> | |||
// main.go | |||
package main | |||
import ( | |||
"example.com/x/mygolib/pugliclib" // exported functions can be called by package consumers | |||
"example.com/x/mygolib/internal/logger" // exported functions only available in 'example.com/x/mygolib' | |||
"example.com/x/mygolib/internal/maths" | |||
) | |||
</syntaxhighlight> | |||
Checkout the [https://github.com/nanomsg/mangos mangos] project for a real example of internal packages. | |||
</blockquote><!-- Internal Packages --> | |||
</blockquote><!-- Defining Packages --> | </blockquote><!-- Defining Packages --> |
Latest revision as of 15:45, 16 July 2022
Basics
- Packages are groups of related code.
- Functions from files belonging to same package can be called as if from same file (no prefix)
- Otherwise, exported functions are callable when a package is imported (and use the packagename as a prefix)
- Unless this is a library, the
main
package is your program's entrypoint (ex. cli). It must have exactly onemain()
function.- Exported symbols in the
main
package are not accessible in subpackages
Imports
import "fmt" import ( "fmt" // builtin pkgs have no module-path prefix "golang.org/x/example/stringutil" // non-builtin pkgs have module-path prefix (incl. local sub-packages) foo "golang.org/x/example/bar" // import 'bar' package, as name 'foo' . "golang.org/x/example/test" // import test, merged into local namespace )
Defining Packages
Anatomy
# project heirarchy myproject/ mypackage/ libfoo.go libbar.go main.go go.mod
myproject/go.mod
// go.mod module github.com/you/myproject go 1.18
myproject/main.go
// main.go package main import "github.com/you/myproject/mypackage" func main() { mypackage.PrintHi(); }
myproject/mypackage/libfoo.go
// mypackage/libfoo.go package mypackage import "fmt" func PrintHi() { fmt.Println("hi") }Scope
Only exported symbols are exposed when a package is imported.
- Exported functions/types/variables are upper-cased.
- If a symbol is not exported, it is only accessible internally within the same package. not even in sub-packages.
- Exported functions within internal packages are only available within that package.
Package Init
Each file within a package can define an
init
function.
This function is evaluated the first time the package is imported.// names/name.go import "fmt" package names var name string func init() { name = "foo" fmt.Println("imported the first time") }Internal Packages
Packages defined within the
internal/
directory can export symbols for internal use, but it will not be publicly available outside of the module.mygolib/ go.mod main.go publiclib/ format.go internal/ logger/ logger.go maths/ division.go multiplication.go// main.go package main import ( "example.com/x/mygolib/pugliclib" // exported functions can be called by package consumers "example.com/x/mygolib/internal/logger" // exported functions only available in 'example.com/x/mygolib' "example.com/x/mygolib/internal/maths" )Checkout the mangos project for a real example of internal packages.