HOW - Go 开发入门(二)

文章目录

HOW - Go 开发入门(一) 我们进行了开发入门的开篇介绍。今天我们主要介绍第 1 步。

基本类型 & struct

Go 的"数据模型"

核心概念

Go 是强类型语言:

go 复制代码
var a int = 10
b := "hello" // 自动推导

常见类型:

  • int / int64
  • float64
  • string
  • bool

struct(最重要)

类似 TS 的 interface + class(但更简单):

go 复制代码
type User struct {
    ID   int
    Name string
    Age  int
}

使用:

go 复制代码
u := User{
    ID:   1,
    Name: "Tom",
    Age:  18,
}

关键点

1. 字段必须大写才能被外部访问

尤其 JSON。

go 复制代码
type User struct {
    Name string // ✅ 可导出
    age  int    // ❌ 外部访问不到
}

这点坑很多人(特别是做 API 时)。


2. JSON tag

做接口必用。

go 复制代码
type User struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

工程用法

  • struct = DB model(GORM)
  • struct = API request/response
  • struct = 配置对象

函数

Go 的函数很"朴素但强大"。

基本写法

go 复制代码
func add(a int, b int) int {
    return a + b
}

简写:

go 复制代码
func add(a, b int) int {
    return a + b
}

多返回值

Go 精髓。

go 复制代码
func divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("divide by zero")
    }
    return a / b, nil
}

使用:

go 复制代码
res, err := divide(10, 2)

关键点:没有异常机制

Go 没有异常机制(try/catch),全靠返回值:

所以你会看到:

go 复制代码
if err != nil {
    return err
}

工程用法

  • 所有 IO / DB / API 都返回 (result, error)
  • 函数尽量短小(Go 风格)

slice / map

最常用容器。

slice(动态数组)

go 复制代码
nums := []int{1, 2, 3}

追加:

go 复制代码
nums = append(nums, 4)

遍历:

go 复制代码
for i, v := range nums {
    fmt.Println(i, v)
}

slice 是引用类型

go 复制代码
a := []int{1, 2, 3}
b := a
b[0] = 100

fmt.Println(a) // [100 2 3]

很容易踩坑


map(字典)

go 复制代码
m := map[string]int{
    "a": 1,
    "b": 2,
}

访问:

go 复制代码
v, ok := m["a"]

map 必须初始化

go 复制代码
var m map[string]int
m["a"] = 1 // ❌ panic

正确:

go 复制代码
m := make(map[string]int)

工程用法

  • slice = 列表数据(接口返回)
  • map = 配置 / 索引 / 快速查找

error 处理(Go 最核心思想)

这是 Go 和其他语言最大差异。


标准写法

go 复制代码
res, err := doSomething()
if err != nil {
    return err
}

自定义 error

go 复制代码
return errors.New("something wrong")

或:

go 复制代码
fmt.Errorf("user %d not found", id)

关键哲学

Go 的理念:

错误是"值",不是"异常"

所以:

  • 不要 try/catch
  • 不要隐藏错误
  • 必须显式处理

工程最佳实践

1. wrap error

go 复制代码
if err != nil {
    return fmt.Errorf("query user failed: %w", err)
}

2. 统一错误处理

在 Web 框架里。比如用 Gin:

go 复制代码
if err != nil {
    c.JSON(500, gin.H{"error": err.Error()})
    return
}

interface

理解即可,但非常关键。

Go 的 interface 和 TS 完全不同。


定义

go 复制代码
type Animal interface {
    Speak() string
}

实现(隐式实现)

go 复制代码
type Dog struct{}

func (d Dog) Speak() string {
    return "wang"
}

不需要 implements!具备解耦系统、易替换实现的优势。


使用

go 复制代码
func makeSound(a Animal) {
    fmt.Println(a.Speak())
}

核心理解

Go 是:

鸭子类型(Duck Typing)

只要实现方法,就自动满足接口。


工程用法

  • 抽象服务(Repository / Service)
  • 解耦依赖(类似 TS interface)
  • mock 测试

总结:5 个认知

要建立这 5 个认知:


struct 是一切的核心

  • 代替 class
  • 代替 DTO
  • 代替 schema

error 是"第一等公民"

看到代码:

go 复制代码
if err != nil

这是正常,不是啰嗦

没有 OOP 那套复杂东西

  • 没有继承
  • 没有泛型复杂设计(虽然现在支持,但少用)

OOP,面向对象,不是"更先进",而是"在某些场景更合适"。虽然 Go 刻意弱化 OOP,但依然能写大型系统。

OOP = 把"数据 + 行为"绑定在一起,将数据和行为绑定,具备封装、继承复用、多态(同一个接口不同实现)等优势。

但是,OOP 同样存在过度设计(类太多、层级复杂、理解成本高)、继承滥用(强耦合、修改困难)、抽象过早等问题。

能力 OOP(Java/TS) Go
封装 class struct + 方法
继承 ❌(用组合)
多态 interface + implements interface(隐式)
抽象 简单直接

interface 是"解耦工具",不是抽象炫技

代码风格 = 简单 + 显式

相关推荐
wei_shuo几秒前
KES 备份恢复与数据灾备实战:物理备份、逻辑备份与PITR完全指南
后端
Ai拆代码的曹操2 分钟前
Netty 堆外内存泄漏从 0 到 1 排查实录:RES 1.2G 堆只有 256M
后端
敲代码的彭于晏25 分钟前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
IT_陈寒31 分钟前
Redis内存飙升的锅,原来是我没搞懂这个过期策略
前端·人工智能·后端
铁皮饭盒1 小时前
26年bunjs, elysia+pg一把梭, redis都省了
前端·javascript·后端
葫芦和十三10 小时前
图解 MongoDB 19|Oplog:复制的真正载体,不是文档是操作
后端·mongodb·agent
葫芦和十三10 小时前
图解 MongoDB 20|复制延迟与 catch up:Secondary 为什么跟不上
后端·mongodb·agent
IT_陈寒15 小时前
SpringBoot自动配置的坑,我的API突然就404了
前端·人工智能·后端
ServBay15 小时前
为什么说 MCP 是 2026 年开发者必须掌握的黄金协议?
后端·mcp