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

代码风格 = 简单 + 显式

相关推荐
Bruce_Liuxiaowei几秒前
Python 实例赋值遮蔽类属性:一个从不报错的静默陷阱
开发语言·python·语法糖
IT_陈寒5 分钟前
Java线程池用错参数,我的服务居然悄悄崩溃了
前端·人工智能·后端
光影少年17 分钟前
Express 中间件原理
后端·node.js·express
aramae1 小时前
MySQL内置函数(7)
开发语言·笔记·后端·mysql·其他
徐小夕2 小时前
存量.doc 文档怎么办?JitWord 开源转换库打通旧文档到在线协同全链路
后端·架构·github
ee又momo2 小时前
一次 JWT Token 过期续期的踩坑记录
后端
五彩小白2 小时前
GO语言装饰器语法
golang
二月龙2 小时前
App 瘦身实战:图片、so 库、资源压缩,安装包体积减小 40%
后端
大勇前进2 小时前
Kotlin 协程实战避坑:90% 的人都会踩的生命周期泄漏问题
后端
苏三说技术3 小时前
Spring AI、LangChain4j、AgentScope、Embabel,哪个AI框架更好?
后端