Go Syntax Basics: Variables, Functions, Errors & Structs

var and short declarations, basic types, functions with multiple return values, idiomatic error handling, pointers, structs and methods — the grammar of Go.

BeginnerUpdated 2026-10-2963K views

Variables and Types

package main

import "fmt"

func main() {
    // var 声明
    var name string = "Go"
    var port = 8080          // 类型推断
    var timeout int          // 零值 0

    // 短变量声明(仅函数内)
    host := "localhost"

    // 常量
    const Pi = 3.14159

    // 基本类型
    var i int = 42
    var f float64 = 3.14
    var b bool = true
    var s string = "hi"
    var by byte = 'A'

    fmt.Println(name, port, timeout, host, i, f, b, s, by)
}
Go has no unused variables — the compiler rejects them. Every type has a zero value (0, false, ""), so nil-pointer dereference is harder to hit accidentally.

Functions and Multiple Return Values

// 多返回值是 Go 的惯例:值 + error
func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("divide by zero")
    }
    return a / b, nil
}

// 命名返回值
func swap(a, b int) (x, y int) {
    y = a
    x = b
    return            // 裸 return
}

// 可变参数 + defer
func sum(nums ...int) (total int) {
    defer func() { total++ }()    // defer 延迟执行
    for _, n := range nums {
        total += n
    }
    return
}

// 函数是一等公民
var fn func(int) int = func(x int) int { return x * 2 }

Error Handling Idioms

Go does not use exceptions. Functions return errors and the caller decides: check immediately, wrap with context, or propagate up.

result, err := divide(10, 0)
if err != nil {
    // 包装错误后向上传递(error wrapping)
    return fmt.Errorf("calc failed: %w", err)
}

// panic/recover 仅用于真正不可恢复的场景
// 例如:程序启动配置错误、map 并发写

// defer + recover 模拟 try/catch(少用)
defer func() {
    if r := recover(); r != nil {
        log.Println("recovered:", r)
    }
}()
errors.Is checks identity, errors.As extracts a typed error, and %w in fmt.Errorf wraps the cause. Modern Go code wraps errors with context at each layer.

Structs, Methods and Interfaces

type User struct {
    ID   int64
    Name string `json:"name"`    // 结构体标签
}

// 值接收者方法
func (u User) Greet() string {
    return "Hi, " + u.Name
}

// 指针接收者方法(可修改字段)
func (u *User) Rename(n string) {
    u.Name = n
}

// 接口:隐式实现(只要有这些方法就算实现)
type Greeter interface {
    Greet() string
}

func hello(g Greeter) { fmt.Println(g.Greet()) }

func main() {
    u := &User{ID: 1, Name: "Go"}
    hello(u)        // User 隐式实现了 Greeter
}

Interfaces are satisfied implicitly — no 'implements' keyword. This makes Go code decoupled: define small interfaces (io.Reader, error) where they are used, not where types are defined.

Friends & Partners