Fundamentals 25 min read

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.

JD Tech Talk
JD Tech Talk
JD Tech Talk
Go Language Basics: Syntax, Types, Concurrency, and Error Handling

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 // equivalent

Constants 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 IFile

This 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      // receive

Example 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.

concurrencyprogramminggoerror handlingfundamentalsSyntax
JD Tech Talk
Written by

JD Tech Talk

Official JD Tech public account delivering best practices and technology innovation.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.