Development Environment Setup
Installing Go
a. Navigate to https://golang.org/dl
b. Download the appropriate installer for your operating system
c. Run the installer (Linux users can extract the archive)
d. Configure environment variables on Linux:
export GOROOT=$PATH:/path/to/go/export PATH=$PATH:$GOROOT/bin/export GOPATH=/home/user/projects/go
e. Windows installation handles environment setup automatically
IDE Configuration (VS Code)
a. Visit: https://code.visualstudio.com/
b. Download the installer for your OS
c. Install or extract the application
d. Go to View → Extensions → search for "go" → install the second result
e. VS Code will prompt to install Go tools, select "Install All"
Debugging Tool: Delve
-
Visit: https://github.com/derekparker/delve/tree/master/Documentation/installation
-
macOS:
brew install go-delve/delve/delve -
Linux/Windows:
go get github.com/derekparker/delve/cmd/dlv
Your First Go Program
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
Code Explanation
package mainis required when compiling to an executablepackagecan have any name when creating libraries- All Go code belongs to exactly one package
fmtis a standard library for formatted I/O operationsfmt.Println()outputs text to the console- Run programs with:
go run filename.go - Executable programs must contain exactly one
main()function
Comments
Single-line: //
Multi-line: /* */
Running the Program
go run hello.go
Output:
hello world
Core Language Concepts
Variable Declaration
var variableName variableType
variableName = value
Important: Go requires all declared variables to be used, otherwise the compiler throws an error.
Shorthand syntax for declaration and assignment:
variableName := value
Functions
package main
import (
"fmt"
)
func add(a int, b int) int {
var result int
result = a + b
return result
}
func main() {
var c int
c = add(22, 33)
fmt.Println(c)
}
Output:
55
Function syntax requirements:
func functionName(param1 type, param2 type) returnType {
}
The opening brace must remain on the same line as the function declaration.
Go Language Features
Automatic Garbage Collection
- Memory management is automatic—no manual allocation/deallocation
- Developers focus on business logic
- Use
newto allocate memory; cleanup happens automatically
Built-in Concurrency
- Goroutines are lightweight threads managed by the Go runtime
- Thousands of goroutines can run simultaneously
- Based on the CSP (Communicating Sequential Processes) model
package main
import (
"fmt"
"time"
)
func printValue(n int) {
fmt.Println(n)
}
func main() {
for i := 0; i < 100; i++ {
go printValue(i)
}
time.Sleep(time.Second)
}
Prepending go to a function call makes it execute concurrently. The time.Sleep() call prevents the main function from exiting before goroutines complete.
Channels
Channels enable communication between goroutines, similar to Unix pipes.
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 3)
ch <- 10
ch <- 20
ch <- 30
fmt.Println(len(ch))
}
Breaking down the channel declaration:
chan intspecifies the channel type3indicates the buffer capacitylen(ch)returns the number of elements currently in the channel
Reading from a channel:
value := <- ch
Channels follow FIFO ordering—the first value written is the first value read.
Summary:
- Send to channel:
channelName <- value - Receive from channel:
variableName := <- channelName
Package Visibility
In Go, identifiers starting with an uppercase letter are exported (public), while lowercase identifiers remain private to their package.
Multiple Return Values
Functions can return multiple values:
package main
import "fmt"
func calculate(a int, b int) (int, int) {
total := a + b
average := total / 2
return total, average
}
func main() {
sum, avg := calculate(100, 200)
fmt.Println(sum, avg)
}
To ignore a return value, use the blank identifier _:
func main() {
sum, _ := calculate(100, 200)
fmt.Println(sum)
}
Package System
- Packages organize related code into directories
- Packages can be imported by other packages
- The
mainpackage generates executable programs - Packages promote code reuse
Package Requirements
packagedeclaration must be the first non-comment line- Only one
mainpackage and onemainfunction per executable - The
mainfunction serves as the program entry point - Unused variables cause compilation errors
Project Structrue
A typical Go project layout:
project/
├── src/ # source code organized by project
├── bin/ # compiled executables
├── pkg/ # compiled libraries
└── vendor/ # third-party dependencies
Set the GOPATH environment variable to the project root directory.
Building and Running Go Code
| Command | Purpose |
|---|---|
go run |
Execute a Go file directly |
go build |
Compile and create a binary |
go install |
Build and place executable in bin/ |
go test |
Run unit or benchmark tests |
go env |
Display Go environment info |
go fmt |
Format source code |
Example: Building an Executable
Given a project at src/myproject/day01/hello/, compile with:
go build myproject/day01/hello
The compiler searches the src directory under GOPATH automatically.
Example: Multi-file Project
Structure:
src/
└── myproject/
└── day01/
└── calculator/
├── main.go
└── compute.go
main.go:
package main
import (
"fmt"
"myproject/day01/calculator"
)
func main() {
result := calculator.Sum(100, 300)
fmt.Println("result=", result)
}
compute.go:
package calculator
func Sum(a int, b int) int {
return a + b
}
Build command:
go build -o bin/calculator.exe myproject/day01/calculator
Custom Package Example
Structure:
src/
└── myproject/
└── day01/
├── mathlib/ # library package
│ ├── add.go
│ └── subtract.go
└── app/ # main application
└── main.go
add.go:
package mathlib
func Add(a int, b int) int {
return a + b
}
subtract.go:
package mathlib
func Subtract(a int, b int) int {
return a - b
}
main.go:
package main
import (
"fmt"
"myproject/day01/mathlib"
)
func main() {
sum := mathlib.Add(100, 300)
diff := mathlib.Subtract(100, 300)
fmt.Println("sum=", sum)
fmt.Println("diff=", diff)
}
Note: Exported funcitons must begin with an uppercase letter to be accessible from other packages.
Unit Testing
Test files must follow the naming pattern: *_test.go
mathlib_test.go:
package mathlib
import (
"testing"
)
func TestAdd(t *testing.T) {
result := Add(5, 6)
if result != 11 {
t.Fatalf("Add failed, got:%v expected:11", result)
}
t.Logf("Add test passed")
}
Test functions must be named with a Test prefix.
Running tests:
go test
go test -v
Standard Go Project Layout
// Current package name
package main
// External package imports
import "fmt"
// Constant declarations
const PI = 3.14
// Global variable declarations
var appName = "gopher"
// Type declarations
type customInt int
// Structure declarations
type person struct{}
// Interface declarations
type writer interface{}
// Main entry point
func main() {
fmt.Println("Hello world!")
}