惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog
D
DataBreaches.Net
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Vulnerabilities – Threatpost
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
The Hacker News
The Hacker News
Latest news
Latest news
博客园_首页
T
Tenable Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
Spread Privacy
Spread Privacy
Martin Fowler
Martin Fowler
Y
Y Combinator Blog
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
I
InfoQ
The Cloudflare Blog
J
Java Code Geeks
C
Cybersecurity and Infrastructure Security Agency CISA
量子位
P
Proofpoint News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
AWS News Blog
AWS News Blog
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
The Register - Security
The Register - Security
M
MIT News - Artificial intelligence
G
Google Developers Blog
Simon Willison's Weblog
Simon Willison's Weblog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Exploit Database - CXSecurity.com
A
Arctic Wolf
D
Darknet – Hacking Tools, Hacker News & Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
Project Zero
Project Zero
P
Privacy International News Feed
Engineering at Meta
Engineering at Meta
G
GRAHAM CLULEY
博客园 - Franky
C
CERT Recently Published Vulnerability Notes

鸟窝

鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 鸟窝 LLM 究竟是如何工作的? Go 实验特性详解 amd64 微架构级别对 Go 程序性能提升多少? Loop Engineering 实践:一次批量实现 8 个 issue,完成夔牛工具的开发 Loop Engineering 实践:我把 RDMA 开发库移植到 Go 语言,花费 239 块钱 傻瓜式RDMA高性能网络开发:从零跑到 400 Gb每秒 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 百度网络监控工具开源第三弹:lidar — 不只是 pingmesh 别只盯着gopacket了,看看这个强大的网络库 大厂的内部工具居然开源了! 一窥百度物理网络秒级监控定位的秘密 如何构建你自己的 Agent 运行时 寻找你代码中的臭味:一个让 AI 帮你嗅出架构腐化的开源 Skill 套壳不丢人!我用Go+AI搓了一个Agent统一编排框架,ClaudeCode-Codex-Pi全被我包了 告别死锁和陈旧语法、告别性能瓶颈:三个开源 Skill,新手Gopher 秒变 Go 语言大神 SPEC和PRD的区别 SPEC和方案设计有什么区别 从需求到上线,让 AI 管理你的整个研发流程! antigravity-cli 使用 CLIProxyAPI, 让最新的 Codex 能够支持国内的各大模型 Clawpatch + codex-review:AI 代码审查工具链的正确打开方式 拆解Manus:沙盒架构深度解析 40+ Claude Code Tips: From Basics to Advanced Ralph 实验:构建 SQLite UI 了解 Manus Sandbox - 您的云计算机 Notex:一个开源 NotebookLM 替代方案的实现 拆解Manus:真正有用的深度报告的生成 Claude Code 使用 我给每个模型服务商『捐』了10块钱,只为了... Codex CLI vs Gemini CLI vs Claude Code:谁是最佳选择? goskills:Claude Skills 功能强大,为我所用 一行代码使用 Claude Skill 和 deepseek langchain + MCP:如虎添翼 Linux 中网络包的一生 godotenv 库介绍 Codex CLI vs Gemini CLI vs Claude Code: Which is the Best? 使用Linux 30年了,我都不知道 ping 8.8 还能这么用? 从 AI 哪里挣钱? Go sync 包近两年发展综述 deepseek-v3.2-exp的闪电索引器
Go之禅 - 基于Rob Pike思想的Go语言哲学
by smallnest · 2025-11-01 · via 鸟窝

Go之禅 - 基于Rob Pike思想的Go语言哲学

1. 简单胜过聪明 (Simple is better than clever)

不要炫技,要解决问题

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

func Max(a, b int) int {

if a > b {

return a

}

return b

}

func Max(a, b int) int {

return (a + b + abs(a-b)) / 2

}

func abs(x int) int {

if x < 0 {

return -x

}

return x

}

2. 清晰胜过简洁 (Clear is better than concise)

代码首先要让人读懂

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

func CalculateUserScore(user *User) int {

totalPoints := 0

for _, activity := range user.Activities {

totalPoints += activity.Points

}

if len(user.Activities) == 0 {

return 0

}

return totalPoints / len(user.Activities)

}

func CalcScore(u *User) int {

if len(u.Acts) == 0 { return 0 }

return func() int { s := 0; for _, a := range u.Acts { s += a.Pts }; return s }() / len(u.Acts)

}

3. 组合胜过继承 (Composition over inheritance)

Go的接口和嵌入体现组合思想

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

type Writer interface {

Write([]byte) (int, error)

}

type Logger interface {

Log(string)

}

type FileLogger struct {

writer Writer

prefix string

}

func (f *FileLogger) Log(message string) {

f.writer.Write([]byte(f.prefix + message))

}

type NetworkLogger struct {

writer Writer

endpoint string

}

func (n *NetworkLogger) Log(message string) {

n.writer.Write([]byte(n.endpoint + ": " + message))

}

4. 接口要小而专注 (Interfaces should be small and focused)

接口越小越好,单一职责

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

type Reader interface {

Read([]byte) (int, error)

}

type Writer interface {

Write([]byte) (int, error)

}

type Closer interface {

Close() error

}

type ReadWriter interface {

Reader

Writer

}

type ReadWriteCloser interface {

Reader

Writer

Closer

}

type FileHandler interface {

Read([]byte) (int, error)

Write([]byte) (int, error)

Seek(int64, int) (int64, error)

Close() error

Stat() (os.FileInfo, error)

Chmod(os.FileMode) error

}

5. 并发不是并行 (Concurrency is not parallelism)

并发是关于结构,并行是关于执行

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

func ProcessTasks(tasks []Task) {

taskChan := make(chan Task, len(tasks))

resultChan := make(chan Result, len(tasks))

for i := 0; i < 3; i++ {

go worker(taskChan, resultChan)

}

for _, task := range tasks {

taskChan <- task

}

close(taskChan)

for i := 0; i < len(tasks); i++ {

result := <-resultChan

fmt.Printf("任务完成: %v\n", result)

}

}

func worker(tasks <-chan Task, results chan<- Result) {

for task := range tasks {

result := processTask(task)

results <- result

}

}

Channel是Go的核心哲学

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

type Counter struct {

ch chan int

value int

}

func NewCounter() *Counter {

c := &Counter{

ch: make(chan int),

}

go c.run()

return c

}

func (c *Counter) run() {

for increment := range c.ch {

c.value += increment

}

}

func (c *Counter) Increment() {

c.ch <- 1

}

func (c *Counter) Add(n int) {

c.ch <- n

}

type MutexCounter struct {

mu sync.Mutex

value int

}

func (c *MutexCounter) Increment() {

c.mu.Lock()

defer c.mu.Unlock()

c.value++

}

7. 错误是值,不是异常 (Errors are values, not exceptions)

显式错误处理胜过异常

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

func ReadConfig(filename string) (*Config, error) {

data, err := os.ReadFile(filename)

if err != nil {

return nil, fmt.Errorf("读取配置文件失败: %w", err)

}

var config Config

if err := json.Unmarshal(data, &config); err != nil {

return nil, fmt.Errorf("解析配置失败: %w", err)

}

return &config, nil

}

func main() {

config, err := ReadConfig("config.json")

if err != nil {

log.Fatal(err)

}

}

8. 不要设计大型接口 (Don't design with interfaces, discover them)

接口应该从使用中发现,而不是预先设计

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

type FileStorage struct {

basePath string

}

func (f *FileStorage) Save(key string, data []byte) error {

return os.WriteFile(filepath.Join(f.basePath, key), data, 0644)

}

func (f *FileStorage) Load(key string) ([]byte, error) {

return os.ReadFile(filepath.Join(f.basePath, key))

}

type Storage interface {

Save(string, []byte) error

Load(string) ([]byte, error)

}

9. 空接口什么都不说 (The empty interface says nothing)

避免过度使用interface{}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

func ProcessUsers(users []User) {

for _, user := range users {

fmt.Printf("处理用户: %s\n", user.Name)

}

}

type Processor interface {

Process() error

}

func RunProcessors(processors []Processor) {

for _, p := range processors {

if err := p.Process(); err != nil {

log.Printf("处理失败: %v", err)

}

}

}

func ProcessAnything(items []interface{}) {

for _, item := range items {

switch v := item.(type) {

case User:

fmt.Printf("用户: %s\n", v.Name)

case Product:

fmt.Printf("产品: %s\n", v.Name)

default:

fmt.Printf("未知类型: %T\n", v)

}

}

}

10. Gofmt的风格就是每个人的风格 (Gofmt's style is no one's favorite, yet gofmt is everyone's favorite)

统一的代码格式胜过个人偏好

1

2

3

4

5

6

7

8

9

10

11

12

13

func CalculateTotal(items []Item, taxRate float64) float64 {

var subtotal float64

for _, item := range items {

subtotal += item.Price * float64(item.Quantity)

}

tax := subtotal * taxRate

return subtotal + tax

}

11. 小规模清晰胜过大规模复杂 (A little copying is better than a little dependency)

适度的代码重复胜过不必要的依赖

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package userservice

func ValidateEmail(email string) bool {

return strings.Contains(email, "@") && len(email) > 5

}

package orderservice

func ValidateEmail(email string) bool {

return strings.Contains(email, "@") && len(email) > 5

}

12. 系统调用、操作系统线程和互斥锁的代价很高,尽量避免 (Syscalls, OS threads, and mutexes are expensive)

理解并发原语的成本

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

func FanOut(input <-chan int, workers int) <-chan int {

output := make(chan int)

for i := 0; i < workers; i++ {

go func() {

for n := range input {

result := process(n)

output <- result

}

}()

}

return output

}

type ExpensiveCounter struct {

mu sync.Mutex

value int

}

func (c *ExpensiveCounter) Get() int {

c.mu.Lock()

defer c.mu.Unlock()

return c.value

}

func (c *ExpensiveCounter) Set(v int) {

c.mu.Lock()

defer c.mu.Unlock()

c.value = v

}

13. 缓存是有用的 (Caching is important)

但要简单明了

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

type Cache struct {

mu sync.RWMutex

data map[string]interface{}

}

func NewCache() *Cache {

return &Cache{

data: make(map[string]interface{}),

}

}

func (c *Cache) Get(key string) (interface{}, bool) {

c.mu.RLock()

defer c.mu.RUnlock()

value, exists := c.data[key]

return value, exists

}

func (c *Cache) Set(key string, value interface{}) {

c.mu.Lock()

defer c.mu.Unlock()

c.data[key] = value

}

var userCache = NewCache()

func GetUser(id string) (*User, error) {

if cached, ok := userCache.Get(id); ok {

return cached.(*User), nil

}

user, err := fetchUserFromDB(id)

if err != nil {

return nil, err

}

userCache.Set(id, user)

return user, nil

}

14. 测试先行,但不要过度测试 (Test first, but don't over-test)

测试重要行为,不是实现细节

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

func TestCalculateDiscount(t *testing.T) {

tests := []struct {

name string

amount float64

userType string

want float64

}{

{"普通用户无折扣", 100.0, "regular", 100.0},

{"VIP用户9折", 100.0, "vip", 90.0},

{"金牌用户8折", 100.0, "gold", 80.0},

}

for _, tt := range tests {

t.Run(tt.name, func(t *testing.T) {

got := CalculateDiscount(tt.amount, tt.userType)

if got != tt.want {

t.Errorf("CalculateDiscount() = %v, want %v", got, tt.want)

}

})

}

}

func TestCalculateDiscountInternals(t *testing.T) {

}

15. 如果你觉得需要泛型,请三思 (If you think you need generics, think again)

Go 1.18+有了泛型,但要谨慎使用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

func Map[T, U any](slice []T, fn func(T) U) []U {

result := make([]U, len(slice))

for i, v := range slice {

result[i] = fn(v)

}

return result

}

func Filter[T any](slice []T, predicate func(T) bool) []T {

var result []T

for _, v := range slice {

if predicate(v) {

result = append(result, v)

}

}

return result

}

numbers := []int{1, 2, 3, 4, 5}

doubled := Map(numbers, func(x int) int { return x * 2 })

evens := Filter(numbers, func(x int) bool { return x%2 == 0 })

type GenericProcessor[T, U, V, W any] interface {

Process(T, U) (V, W, error)

Validate(T) bool

Transform(U) V

}

16. 性能问题通常出在算法,不是语言 (Performance problems are usually algorithmic)

优化算法比优化语言特性更重要

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

func FindDuplicates(nums []int) []int {

seen := make(map[int]bool)

var duplicates []int

for _, num := range nums {

if seen[num] {

duplicates = append(duplicates, num)

} else {

seen[num] = true

}

}

return duplicates

}

func FindDuplicatesSlow(nums []int) []int {

var duplicates []int

for i := 0; i < len(nums); i++ {

for j := i + 1; j < len(nums); j++ {

if nums[i] == nums[j] {

duplicates = append(duplicates, nums[i])

break

}

}

}

return duplicates

}

17. 数据结构,不是算法,才是编程的核心 (Data structures, not algorithms, are central to programming)

正确的数据结构让程序简单明了

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

type UserIndex struct {

byID map[string]*User

byEmail map[string]*User

users []*User

}

func NewUserIndex() *UserIndex {

return &UserIndex{

byID: make(map[string]*User),

byEmail: make(map[string]*User),

users: make([]*User, 0),

}

}

func (ui *UserIndex) AddUser(user *User) {

ui.byID[user.ID] = user

ui.byEmail[user.Email] = user

ui.users = append(ui.users, user)

}

func (ui *UserIndex) FindByID(id string) *User {

return ui.byID[id]

}

func (ui *UserIndex) FindByEmail(email string) *User {

return ui.byEmail[email]

}

func (ui *UserIndex) GetAllUsers() []*User {

return ui.users

}

type BadUserStorage struct {

users []*User

}

func (us *BadUserStorage) FindByID(id string) *User {

for _, user := range us.users {

if user.ID == id {

return user

}

}

return nil

}


Go之禅总结: Go语言强调简单、清晰、组合和并发。Rob Pike的设计哲学体现在语言的每个角落:小而专注的接口、显式的错误处理、通过通信共享内存的并发模型,以及对简单性的坚持。Go不追求语言特性的丰富性,而是追求解决实际问题的有效性。