package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
// Variable declaration
var name string = "Go"
var age int = 10
// Short declaration (type inference)
language := "Go"
version := 1.21
// Multiple declarations
var x, y, z int = 1, 2, 3
a, b, c := "hello", 42, true
// Constants
const Pi = 3.14159
const (
StatusOK = 200
StatusError = 500
)
// Basic types
var b bool = true
var s string = "hello"
var i int = 42 // int, int8, int16, int32, int64
var u uint = 42 // uint, uint8, uint16, uint32, uint64
var f float64 = 3.14 // float32, float64
var c complex128 = 1+2i // complex64, complex128
var by byte = 255 // alias for uint8
var r rune = 'A' // alias for int32 (Unicode code point)
// Zero values
var defaultInt int // 0
var defaultStr string // ""
var defaultBool bool // false
// Arrays (fixed size)
var arr [5]int = [5]int{1, 2, 3, 4, 5}
arr2 := [...]int{1, 2, 3} // compiler counts elements
// Slices (dynamic size)
slice := []int{1, 2, 3, 4, 5}
slice2 := make([]int, 5) // length 5
slice3 := make([]int, 5, 10) // length 5, capacity 10
// Slice operations
slice = append(slice, 6, 7) // append elements
sub := slice[1:4] // slice from index 1 to 3
length := len(slice) // length
capacity := cap(slice) // capacity
// Copy slice
dest := make([]int, len(slice))
copy(dest, slice)
// Create a map
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
// Map literal
scores := map[string]int{
"Alice": 95,
"Bob": 87,
}
// Access and check existence
value := scores["Alice"]
value, exists := scores["Alice"]
if exists {
fmt.Println(value)
}
// Delete a key
delete(scores, "Bob")
// Iterate over map
for key, value := range scores {
fmt.Printf("%s: %d\n", key, value)
}
// If statement
if x > 10 {
fmt.Println("greater")
} else if x < 10 {
fmt.Println("less")
} else {
fmt.Println("equal")
}
// If with initialization
if val := compute(); val > 0 {
fmt.Println(val)
}
// Switch statement
switch day {
case "Monday":
fmt.Println("Start of week")
case "Friday":
fmt.Println("End of week")
default:
fmt.Println("Midweek")
}
// Switch without condition
switch {
case x < 0:
fmt.Println("negative")
case x > 0:
fmt.Println("positive")
default:
fmt.Println("zero")
}
// Basic for loop
for i := 0; i < 10; i++ {
fmt.Println(i)
}
// While-style loop
for x < 100 {
x *= 2
}
// Infinite loop
for {
// break to exit
break
}
// Range over slice
nums := []int{1, 2, 3}
for index, value := range nums {
fmt.Printf("%d: %d\n", index, value)
}
// Range over map
for key, value := range myMap {
fmt.Printf("%s: %v\n", key, value)
}
// Range over string (runes)
for i, char := range "hello" {
fmt.Printf("%d: %c\n", i, char)
}
// Basic function
func add(a int, b int) int {
return a + b
}
// Multiple return values
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
// Named return values
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // naked return
}
// Variadic function
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
// Anonymous function / closure
square := func(x int) int {
return x * x
}
// Define a struct
type Person struct {
Name string
Age int
}
// Create instances
p1 := Person{Name: "Alice", Age: 30}
p2 := Person{"Bob", 25} // positional
var p3 Person // zero value
// Access fields
fmt.Println(p1.Name)
p1.Age = 31
// Pointer to struct
p := &Person{Name: "Charlie", Age: 35}
p.Name = "Charles" // automatic dereferencing
// Embedded struct (composition)
type Employee struct {
Person // embedded
Title string
}
emp := Employee{
Person: Person{Name: "Dave", Age: 40},
Title: "Engineer",
}
fmt.Println(emp.Name) // access embedded field
type Rectangle struct {
Width, Height float64
}
// Value receiver
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// Pointer receiver (can modify the struct)
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
// Usage
rect := Rectangle{10, 5}
fmt.Println(rect.Area()) // 50
rect.Scale(2)
fmt.Println(rect.Area()) // 200
// Define an interface
type Shape interface {
Area() float64
Perimeter() float64
}
// Implement interface (implicit)
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * c.Radius
}
// Use interface
func printShape(s Shape) {
fmt.Printf("Area: %.2f\n", s.Area())
}
// Empty interface (any type)
var any interface{}
any = 42
any = "hello"
// Type assertion
str, ok := any.(string)
if ok {
fmt.Println(str)
}
// Type switch
switch v := any.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
default:
fmt.Println("unknown type")
}
// Return error
func readFile(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read file: %w", err)
}
return data, nil
}
// Handle error
data, err := readFile("config.json")
if err != nil {
log.Fatal(err)
}
// Custom error type
type ValidationError struct {
Field string
Message string
}
func (e ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
// Panic and recover
func safeDivide(a, b int) (result int) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
result = 0
}
}()
return a / b // panics if b is 0
}
// Start a goroutine
go func() {
fmt.Println("Running in goroutine")
}()
// Goroutine with function
func worker(id int) {
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second)
fmt.Printf("Worker %d done\n", id)
}
go worker(1)
go worker(2)
// Wait for goroutines
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
worker(id)
}(i)
}
wg.Wait()
// Create channel
ch := make(chan int) // unbuffered
ch := make(chan int, 10) // buffered with capacity 10
// Send and receive
ch <- 42 // send
value := <-ch // receive
// Close channel
close(ch)
// Receive with ok check
value, ok := <-ch
if !ok {
fmt.Println("Channel closed")
}
// Range over channel
for value := range ch {
fmt.Println(value)
}
// Select statement
select {
case msg := <-ch1:
fmt.Println("Received from ch1:", msg)
case msg := <-ch2:
fmt.Println("Received from ch2:", msg)
case ch3 <- 42:
fmt.Println("Sent to ch3")
case <-time.After(time.Second):
fmt.Println("Timeout")
default:
fmt.Println("No communication")
}
// Defer execution until function returns
func readFile() {
file, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close() // executed when function returns
// work with file...
}
// Multiple defers (LIFO order)
func example() {
defer fmt.Println("first")
defer fmt.Println("second")
defer fmt.Println("third")
// Output: third, second, first
}
// Declare pointer
var p *int
// Get address
x := 42
p = &x
// Dereference
fmt.Println(*p) // 42
*p = 100 // x is now 100
// New function
p := new(int) // allocates zeroed int, returns pointer
*p = 42
// Pointers with functions
func increment(x *int) {
*x++
}
val := 10
increment(&val)
fmt.Println(val) // 11
// Single import
import "fmt"
// Multiple imports
import (
"fmt"
"os"
"strings"
)
// Aliased import
import (
f "fmt"
. "math" // dot import (use without prefix)
_ "image/png" // blank import (side effects only)
)
// Exported names (capitalized)
func PublicFunction() {} // exported
func privateFunction() {} // not exported
// Strings
import "strings"
strings.Contains("hello", "ell") // true
strings.Split("a,b,c", ",") // ["a", "b", "c"]
strings.Join([]string{"a", "b"}, "-") // "a-b"
strings.ToUpper("hello") // "HELLO"
strings.TrimSpace(" hello ") // "hello"
// String formatting
import "fmt"
fmt.Sprintf("Name: %s, Age: %d", name, age)
fmt.Printf("Value: %v, Type: %T\n", val, val)
// JSON
import "encoding/json"
data, _ := json.Marshal(obj) // struct to JSON
json.Unmarshal(data, &obj) // JSON to struct
// HTTP
import "net/http"
resp, err := http.Get("https://api.example.com")
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
// Time
import "time"
now := time.Now()
time.Sleep(time.Second * 2)
formatted := now.Format("2006-01-02 15:04:05")