Golang packages: Difference between revisions

From wikinotes
 
(8 intermediate revisions by the same user not shown)
Line 4: Line 4:
* Functions from files belonging to same package can be called as if from same file (no prefix)
* 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)
* Otherwise, exported functions are callable when a package is imported (and use the packagename as a prefix)
* The <code>main</code> package is your program's entrypoint (ex. cli). It must have exactly one <code>main()</code> function.
* 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 15: 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 78: Line 83:
</blockquote><!-- Anatomy -->
</blockquote><!-- Anatomy -->


== Exported Functions ==
== Scope ==
<blockquote>
<blockquote>
Only exported symbols are exposed when a package is imported.
Only exported symbols are exposed when a package is imported.


* Exported functions/types/variables are upper-cased.
* Exported functions/types/variables are upper-cased.
* If a symbol is not exported, it is only accessible internally within the same package
* If a symbol is not exported, it is only accessible internally within the same package. not even in sub-packages.
</blockquote><!-- Exported Functions -->
* Exported functions within internal packages are only available within that package.


== init function ==
</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 106: Line 113:
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- init function -->
</blockquote><!-- init function -->
</blockquote><!-- Defining Packages -->


= Internal Packages =
== Internal Packages ==
<blockquote>
<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.
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">
<syntaxhighlight lang="bash">
mygolib/
mygolib/
  go.mod
  main.go
  publiclib/
    format.go
   internal/
   internal/
     someInternalPackage/
     logger/
     someOtherInternalPackage/
      logger.go
     ...
     maths/
  go.mod
      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>
</syntaxhighlight>


{{ TODO |
Checkout the [https://github.com/nanomsg/mangos mangos] project for a real example of internal packages.
full example  
}}
</blockquote><!-- Internal Packages -->
</blockquote><!-- Internal 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 one main() 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.