Golang: Packages
Introduction
In this 11th part of the series, we will be covering packages in golang. Package is a cool way to organize code in large projects. We can create a separate file which can include certain helper functions or variables from other files or scripts. There are couple of types of packages like packages from the standard library, open sourced community packages and custom packages that you can build of your own. In this particular section, we will be covering the fundamentals of packages and exploring the standard library in golang.
What is a Package ?
Package in simplest of terms is a collection of go scripts that can serve a purpose. Just like fmt
has several functions like Println
, Printf
, Scan
, Scanf
, etc. most packages have functions that we can use in our own programs to solve a simple problem. We have already created many packages but none of them have been super useful so far, we just used the statement package main
and didn’t use the package anywhere. Every package has a entry point called main
along with a entry function main
which is triggered when we run the package.
- package_name
- script_1.go
- script_2.go
- sub_package_name
- utility_1.go
- go.mod
The above is a simple folder structure for a package in golang, we have the package itself as the name of the folder. Inside of the package folder, we would have the scripts or sub-packages if any. Also there is a go.mod
file in all go source package folders which contain the meta information about the package and it’s dependencies.
Let’s take a look at the fmt package source code, it has a print.go file which has all the functions associated with printing, similarly separate files for different core functionality.
We will soon into the details of packages in this series. Right now, we only care about the fundamentals of a package in golang.
Importing Packages
We have been already importing a package since writing our hello world in go, the fmt
package which holds some functions for formatting, printing, logging and various string input/output manipulation.
import "fmt"
So, we have used the simple import "package"
statement, but there are a couple of more ways to import packages if we have multiple packages to import.
import (
"fmt"
"math"
)
Using the ()
and by specifying the name of the package we can import multiple packages at once. Also there is a harder way out there, if you really like to toil hard.
import "fmt"
import "math"
This is generally avoided as it just looks too pythonic, we are in golang.
Aliasing Imported packages
We can alias an package a name whatever we want for the usage in the rest of the script file. This allows a bit better semantics of longer package names into readable code.
package main
import (
"fmt"
r "math/rand"
)
func main() {
fmt.Println(r.Int())
}
$ go run import.go
3454565657742387432
We have imported the package math/rand
, here rand is a sub package of the main package math. Hence we have aliased the rand package as r
and thus, we can use r to access all the functions and other types from the package.
Blank Package Import
We can even import the package but not use it without getting a compilation error. So, the blank identifier is used in golang to ignore the initialized or returned values from any context and avoid the compilation warning or errors.
package main
import (
_ "fmt"
)
func main() {
}
$ go run blank_import.go
Here, we have imported fmt
package with a _
blank identifier but we didn’t use it anywhere, still we don’t get any error messages and it compiled the code successfully.
Standard Library Packages
The Golang Standard Library has some good number of packages which can be used for some general tasks like formatting input/output, file handling, web requests, system commands, etc. You can check out the entire list along with the documentation on the official website.
We can import these standard library packages just by parsing their name in the string quotes like we did with fmt
as "fmt"
. We have previously used the rand
package from the math standard library package as a sub-package by using the statement "math/rand"
, if we want we can import the entire math
package as "math"
but that’s unwanted and we import only the package which we really need.
There are other packages as well like bufio
which is used for reading and performing operations with text, os
for working with files systems and operating system level stuff, and other packages which are specific to use cases like rendering templates, time, sorting, math operations, encoding, etc. We will dive into some of them throughout this series.
Installing Packages
We can now get into installing other packages which are not in the standard library. You can get the documentation along with all references for a particular package on the official Golang package repository. We use the CLI command to grab the packages into our GOPATH
. OK, GOPATH, we have not covered this!
GOPATH
GOPATH is the path or the location in your system’s disk where all the packages and modules are stored. You can get the default location of your GOPATH environment variable from the simple shell command.
$ echo $GOPATH
C:\Users\acer\go
It has a few folders namely, bin
, pkg
, and src
. These folder server different purpose like:
bin
for storing the binaries generated fromgo install
commandpkg
for storing pre-compiled source files and objects for quicker generation of executables and compilation.src
for storing all the go source files of packages and modules.
Go Get command
Now, let’s see how to install a package from the go community on GitHub.
go get github.com/gorilla/mux
We have installed a package which is a powerful HTTP router and a URL dispatcher and it can also be used to make web applications. It’s called mux
, we won’t be using it right away just to get a feel for installing and playing with packages at the moment.
After executing the command go get
you should see a folder to be added in the $GOPATH\pkg\mod
as github.com\gorilla
and inside of it we should have a mux folder with the latest version. So, the go get
command is used to download and install a package along with its all dependencies.
Set up a project for using a package
Now, we have got the package so we can import it from anywhere in our go environment.
Create a new folder (any name)
You can test a go package from a isolated environment from the GOPATH by creating using the mod command.
The mod init
command is a official way to create modules in golang and it creates kind of a environment to work on a templated project and structure the project/module/package properly.
go mod init
Install the packages
We have already installed the package but that was a global install in the GOPATH, so we need to install it in this module.
go get github.com/gorilla/mux
Use the package
Now, we can move into actually using the package in our source go file. We won’t do any thing complicated just a simple web server. It’s too easy don’t worry!
package main
import (
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/", Server)
http.ListenAndServe(":8000", router)
}
func Server(writer http.ResponseWriter, request *http.Request) {
writer.Write([]byte("Hello Mux!"))
}
We firstly setup a router(a pair of HTTP route with some logic) from the NewRouter function provided by mux
. We’ll attach a function to this newly created router by pairing a URL with a function. So, in simple terms when the mentioned URL is visited or a GET request is sent(don’t get into too much details) we want a function to be invoked or called which does something. Finally we will set up a web server that listens at a port with the created router.
The final piece is the function which we will call when the URL is visited i.e. the Server
function it can be any name. The function needs to have two arguments as it is invoked by a router, the writer and the request. The Writer is a Response writer i.e. to write the message to the server. We will simply use the Write function to simply print a array of bytes.
The type of the writer is specifically http.ResponseWriter
as we want to write a simple HTTP response header. Also the request is a http.Request type as we simply accept a HTTP request.
So, on running the following script, we will be able to see a simple HTTP response on the localhost at port 8000
or on your provided port.
go run main.go
That’s it from this part. Reference for all the code examples and commands can be found in the 100 days of Golang GitHub repository.
Conclusion
So, we were able to dive a bit deeper in golang packages and modules. We covered from installation to importing packages in Golang, we also touched on basics of initializing a module in Golang. Hopefully, we were able to get the basics covered when it comes to packages in Golang.
Thank you for reading. If you have any questions or feedback, please let me know in the comments or on social handles. Happy Coding :)