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

代码风格 = 简单 + 显式

相关推荐
Chester_19993 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
2601_962055974 小时前
跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围
spring boot·后端·tomcat
EXI-小洲4 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员5 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导5 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan5 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
m0_695251495 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
Lost of 程序猿6 小时前
ASP.NET Core API 幂等性设计深度实战:从一次重复申领事故说起
后端·asp.net
大衛說6 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
QQ_21696290967 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端