2.8 KiB
title | date | tags | excerpt | ||
---|---|---|---|---|---|
Learning Go: Day Two | 2024-05-02T08:00:00.0Z |
|
In part two, I take a look at how to organise code into packages |
Welcome to Part Two of my series on Learning Go for WeblogPoMo. In this part, I'm going to look at how to organise my code into separate packages, so that I don't have to store everything in once single file.
Creating a package
This was fairly straightforward. Packages are noted by the package <name>
directive at the start of the file. You can even see that in main.go
, which has package.main
at the start. So, to create a package I added a directory for it (I'm calling it maths
1), and then added a maths.go
file to it. For now, I'll just move the multiply
function to it:
package maths
func multiply(a, b int) int {
return a * b
}
Fairly straightforward, right?
Importing and running the code
So, I can't just do import "maths"
, because that doesn't seem to resolve. Instead, I have to refer to my entire module name, and then append the path to it:
import "lewisdale.dev/learn-go/maths"
So now I should be able to use my imported module and call maths.multiply
, right?
func main() {
fmt.Println(sayHello())
num := maths.multiply(2, 5)
fmt.Printf("2 * 5 = %d\n", num)
}
go run main.go
> ./main.go:16:15: undefined: maths.multiply
Wait, what?
So, it turns out in Go, there's no explicit export keyword. Instead, if you want a function to be exported you have to capitalise the first letter. Lowercase functions are implicitly private.
// maths.go
package maths
func Multiply(a, b int) int {
return a * b
}
And then we can do
// main.go
func main() {
fmt.Println(sayHello())
num := maths.Multiply(2, 5)
fmt.Printf("2 * 5 = %d\n", num)
}
As a useful extra, the Go plugin on VS Code2 even organised my imports into one import ()
statement:
// main.go
package main
import (
"fmt"
"lewisdale.dev/learn-go/maths"
)
The vendor directory
When I was looking up how to create and import modules, I did find this useful StackOverflow comment that mentions that Go > 1.5 has support for a vendor
directory, that allows you to put code inside a vendor
directory, and Go will lookup the package without requiring the local module prefix.
I'm not going to use this, just because I'm probably going to reinvent the wheel a few times over the course of this series and I don't know the standard library well enough3 to trust myself to not accidentally tread all over it, but it's good to know it's there.