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 是"解耦工具",不是抽象炫技

代码风格 = 简单 + 显式

相关推荐
第九序言T7 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
学长毕设7 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
滴滴答答哒8 小时前
ASP.NET Core + FaceRecognitionDotNet 人脸识别实战:DI 单例、特征向量持久化与 1:N 比对
后端·asp.net
龙亘川8 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
程序喵大人8 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
Raas1009 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
专注仿真9 小时前
线性回归和逻辑回归算法详解
开发语言·人工智能·python·大模型训练·控制算法
jimy110 小时前
C++ 中的 `T&&`:右值引用与转发引用
开发语言·c++
captain37610 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
呆呆虫1210 小时前
用 orjson 加速 SerpBase 响应解析:基准对比与注意事项
开发语言·php