Packages

In Go, source files are organized into system directories called packages.

  • Go program is made up of packages. Programs start running in package main.

      package main                // this source file won't have to reside in the directory "main". 
    
      import "fmt"
    
      func main() {
          fmt.Println("Hello, playground")
      }
    
  • Packages is used to organize maintainable and reusable code across the Go applications.

  • The naming convention for Go package is tie the package name to the directory structure. Within a single folder, the package name will be same for the all source files which belong to that directory.We develop our Go programs in the $GOPATH directory, where we organize source code files into directories as packages.

  • Visibility in Go (Exported/Unexported Identifiers In Go). There are no public/private/protected keywords in Go. All identifiers will be exported to other packages if the first letter of the identifier name starts with an uppercase letter. The functions and types will not be exported to other packages if we start with a lowercase letter for the identifier name.

    Ref : Basic GoLang : Why and What - Part 4 : Naming & Visibility

  • Go doesn't have any notion of "sub"-package. They're just packages. All packages behave the same , even though some packages are in the subdirectory of another.

  • Import cycle are not allowed in Go.

Examples :

src                             // forder structure
|___ hello
     |___ foo
     |    |___ foo.go
     |    |___ db.go
     |___ bar.go
     |___ main.go
package main                    // src/hello/main.go
                                // althought it is the main entry of the program, 
                                // it is NOT in the main folder.
import (
    "fmt"
    "hello/foo"
    _ "hello/foo"               // see section - Init() Function
                                // blank identifier ( _ ) as the package alias name, 
                                // so the compiler ignores the error of not using the 
                                // package identifier, but will still invoke the init function.
)

func main() {
    // bar.go and main.go are in the same package
    // we can call Say() & barsecret() directly , even though barsecret() are private function.
    fmt.Println(Say(), "/", Getbar1(), "/", Bar2, "/", Bar3, "/", barsecret())

    // bar.go and main.go are in the different packages , call foo.Say() instead.
    // we cannot see foosecret() here !
    fmt.Println(foo.Say(), "/", foo.Getfoo1(), "/", foo.Foo2, "/", foo.Foo3)
}
package main                    // src/hello/bar.go

var bar1 int = 81
var Bar2 int = 82
var Bar3 = "l am Bar3"

func barsecret() string {       // lowercase letter - private function
    return "l love foo"
}
func Getbar1() int {            // uppercase letter - exported, getter function
    return bar1
}
func Say() string {             // exported function
    return "hello! l am bar"
}
package foo                     // src/hello/foo/foo.go
                                // import "hello" will cause "import cycle not allowed"

var foo1 int = 77
var Foo2 int
var Foo3 string = "l am Foo3"

func foosecret() string {       // lowercase letter - private function
    return "l love bar"
}
func Getfoo1() int {            // uppercase letter - exported, getter function
    return foo1
}
func Say() string {             // exported function
    return "hello! l am foo"
}
[output]
Initializing db ...                                     // to be explained in "Init() Function"
hello! l am bar / 81 / 82 / l am Bar3 / l love foo
hello! l am foo / 77 / 0 / l am Foo3

Init() Function

When you write Go packages, you can provide a function “init” that will be called at the beginning of the execution time. The init() method can be used for adding initialization logic into the package.

package foo                     // src/hello/foo/db.go

import "fmt"

func init() {
    fmt.Println("Initializing db ...")
}

In some contexts, we may need to import a package only for invoking it’s init method, where we don’t need to call forth other methods of the package. If we imported a package and are not using the package identifier in the program, Go compiler will show an error. In such a situation, we can use a blank identifier ( _ ) as the package alias name, so the compiler ignores the error of not using the package identifier, but will still invoke the init function.

Init() function is called in each package before the main() call. There can be few of them in different files.

Package Alias

package main

import (
    format "fmt"
)

func main() {
    format.Println("this is an alias")
}

[output]
this is an alias

We can use alias names for packages to avoid package name ambiguity.

package main

import (
        mongo "webapp/libs/mongodb/db"
        mysql "webapp/libs/mysql/db"      
)

Remote Imports

If you need to install external packages in your application, you have to install them locally on your machine with the go install command.

Suppose you want to use a package which resides at http://github.com/author/gopackage/hello, and hello is the package name, you install it with the command:

go install github.com/author/gopackage/hello

This will fetch the packages from their source control location and place them in the correct locations within your GOPATH/src.

Once installed, to import it in your code, use :

import home "github.com/author/gopackage/hello"         // "home" is an alias name

When you try to build a program with this import path, the go build command will search your local GOPATH/src for this package and import it correctly.

Packages in the standard library are found in your GOROOT, which is where Go is installed on your computer.

Ref :

Further Reference:

  1. How to Write Go Code
  2. Exported/Unexported Identifiers In Go
  3. How Packages Work in Go
  4. Understanding Golang Packages
  5. Next Steps in Go: Code Organization
  6. Basic GoLang : Why and What - Part 1 : Overcoming Dependency Flaws

results matching ""

    No results matching ""