Go Language Basics: Syntax, Types, Concurrency, and Error Handling
This article introduces Go (Golang) fundamentals for developers familiar with other object‑oriented languages, covering basic syntax, variable and constant declarations, nil and zero values, methods, packages, pointers, struct‑based OOP, interfaces, goroutines, channels, mutexes, and the language's simple error‑handling mechanisms.
Introduction
Go (also known as Golang) is a statically typed, compiled language created by Google. It combines C‑like syntax with memory safety, garbage collection, and CSP‑style concurrency.
Scope
The article targets readers who have learned Java or PHP and want to understand Go by comparing its features with Java in four areas: basic syntax, object‑oriented programming, concurrency, and error handling.
1. Basic Syntax
Variables, Constants, nil and Zero Values, Methods, Packages, Visibility, Pointers
Go offers two ways to declare variables: using the var keyword (type follows the name) or the short declaration operator := . Examples:
var num int
var result string = "this is result"
num := 3
var num int = 3 // equivalentConstants are declared with const and cannot be changed after definition:
const laugh string = "go"Uninitialized variables have the value nil (similar to Java's null ) and receive a zero value appropriate to their type ( 0 , false , "" ).
Methods are defined with the func keyword:
func MethodName(p1 Param, p2 Param) int {}A simple Hello‑World program:
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}Go supports multiple return values, which are useful for error handling:
func add(a, b int) (int, error) {
if a < 0 || b < 0 {
return 0, errors.New("only non‑negative integers allowed")
}
return a + b, nil
}Variadic functions use ... :
func myfunc(numbers ...int) {
for _, n := range numbers {
fmt.Println(n)
}
}
myfunc(slice...)Visibility in Go is package‑level and determined by the first letter of an identifier; exported names start with an uppercase letter.
Package declaration and imports are straightforward:
package main
import "fmt"
func main() { fmt.Println("Hello") }Pointers work like in C; the address operator & obtains a pointer and the dereference operator * accesses the value:
i := 0
fmt.Println(&i) // prints address
func add(a *int, b *int) int { return *a + *b }2. Object‑Oriented Programming
Structs as Classes
Go does not have a dedicated class keyword; the struct type serves that purpose. Example:
type Student struct {
id int
name string
male bool
score float64
}
func NewStudent(id uint, name string, male bool, score float64) *Student {
return &Student{id, name, male, score}
}
student := NewStudent(1, "Alice", true, 95)
fmt.Println(student)Methods on Structs
func (s Student) GetName() string { return s.name }
func (s *Student) SetName(name string) { s.name = name }Interfaces
Interfaces in Go are satisfied implicitly: a type implements an interface by providing all its methods, without an explicit implements clause.
type IFile interface {
Read(buf []byte) (n int, err error)
Write(buf []byte) (n int, err error)
Seek(off int64, whence int) (pos int64, err error)
Close() error
}
// Any type with these methods satisfies IFileThis non‑intrusive design avoids the “interface explosion” problem common in Java or PHP.
3. Concurrency and Multithreading
Goroutine
Goroutines are lightweight threads started with the go keyword:
func say(s string) { fmt.Println(s) }
func main() {
go say("world")
say("hello")
}Mutex
Synchronization can be achieved with sync.Mutex :
type SafeCounter struct {
v map[string]int
mux sync.Mutex
}
func (c *SafeCounter) Inc(key string) {
c.mux.Lock()
c.v[key]++
c.mux.Unlock()
}Channel
Channels enable communication between goroutines:
ch := make(chan int)
ch <- v // send
v := <-ch // receiveExample of parallel sum calculation:
func sum(s []int, c chan int) {
total := 0
for _, v := range s { total += v }
c <- total
}
func main() {
s := []int{7,2,8,-9,4,0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c
fmt.Println(x, y, x+y)
}4. Error Handling
error Interface
The built‑in error interface defines a single method Error() string . Functions typically return a value and an error :
func Foo(param int) (n int, err error) { /* ... */ }
if n, err := Foo(0); err != nil {
// handle error
} else {
// use n
}defer
defer schedules a function call to run after the surrounding function returns, similar to finally in Java:
func ReadFile(name string) ([]byte, error) {
f, err := os.Open(name)
if err != nil { return nil, err }
defer f.Close()
// read file …
}panic and recover
panic aborts the current goroutine; recover can catch a panic when called inside a deferred function:
func divide() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Runtime panic caught: %v\n", r)
}
}()
i, j := 1, 0
k := i / j // triggers panic
fmt.Printf("%d / %d = %d\n", i, j, k)
}
func main() { divide(); fmt.Println("divide finished") }Conclusion
The article provides a concise overview of Go’s core features—syntax, struct‑based OOP, interfaces, goroutines, channels, and error handling—enabling beginners to start writing Go programs and explore more advanced topics such as concurrency patterns.
JD Tech Talk
Official JD Tech public account delivering best practices and technology innovation.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.