• 让 Go 的错误处理更加强大

    Go 所提供的默认的 `errors` 包有很多的不足。编写多层架构应用程序并使用 API 公开功能的时候,相比于单纯的 `string` 类型的值,更需要具有上下文信息的错误处理。意识到这个缺点后,我开始实现一个更强大,更优雅的 error 包。这是一个逐渐演化的过程,随着时间推移,我需要在这个包中引入更多的功能。 在此,我们会探讨我们如何使用一个 `CustomError` 数据类型为应用中带来更多的价值,并且使错误处理更强大。 首先需要明白的是,如果实现了 `Error()` ...

  • 如何以及为什么在 Go 中编写枚举

    一个**枚举**(enum,**enumerator** 的缩写),是一组命名的常量值。枚举是一个强大 的工具,让开发者可以创建复杂的常量集,而这些常量集有着有用的名称和简单且唯一的取值。 *在我们走远之前,我想提一下[我最近启动了 Go Mastery,一门动手的 Golang 课程](https://qvault.io/go-mastery-course/)。如果想要了解更多关于 Go 的信息,请尝试下该课程,现在让我们回到枚举上面。* ## 语法示例 在一个常量声明中,[...

  • Go 服务中 HTTP 请求的生命周期

    Go 语言对于编写 HTTP 服务来说是一个常见且非常合适的工具。这篇博文通过一个 Go 服务来探讨一个典型 HTTP 请求的路由,涉及路由,中间件以及比如并发之类的相关问题。 为了有具体的代码可以参考,让我们先从这段简单的服务代码开始(来自于 [https://gobyexample.com/http-servers](https://gobyexample.com/http-servers)) ```go package main import ( "fmt" "...

  • 120
    Go:程序如何恢复(recover)?

    ![由 Renee French 创作的原始 Go Gopher 作品,为“ Go 的旅程”创建插图。](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20201002-Go-How-Does-a-Program-Recover/1_4zRau44piN5HjUnTnJsMOw.png) 当程序无法适当处理错误时,比如无效的内存访问,Go 中的 panic 就会被触发。如果错误是意料之外,且没有其他方式处...

  • 120
    Go:多错误管理

    ![由Renee French创作的原始Go Gopher制作的“ Go的旅程”插图。](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20200901-Go-Multiple-Errors-Management/Illustration.png) Go 语言中的错误(error)管理总是能引起争论,同时,在关于使用 Go 语言的时候,开发者面对最大的挑战的[年度调查](https://blog.gola...

  • 120
    Go: 内置函数优化

    ![由 Renee French 创作的原始 Go Gopher 作品,为“ Go 的旅程”创作的插图。](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20200813-Go-Built-in-Functions-Optimizations/Illustration.png) ℹ️ 这篇文章基于 Go 1.13。 Go 语言提供内置函数来辅助开发者处理 channel,slice,或者 map。...

  • 当在 Go 中使用微服务还不够时:介绍 DDD Lite

    当我开始用 Go 工作时,社区并不看好类似 DDD(Domain-Driven Design 领域驱动设计)和清晰架构这样的技术。我很多次听到这样的声音:*“不要在 Golang 中用 Java!”,“我已经在 Java 中见过了,请别这样做!”*。 这些时候,我已经有了近 10 年的 PHP 和 Python 经验。我已经见过太多糟糕的事情了。我记得所有那些“八千行”(有着 8 千行以上代码的方法 😉)和没有人愿意维护的应用。我查看了这些丑陋怪物以前的 Git 历史,他们最初看起来是无害...

  • 120
    Go:字符串以及转换优化

    ![由 Renee French 创作的原始 Go Gopher 作品,为“ Go 的旅程”创作的插图。](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20200610-Go-String-and-Conversion-Optimization/Illustration.png) ℹ️ 这篇文章基于 Go 1.14。 在 Go 语言中,将 byte 数组转换为 string 时,随着转换后字符串...

  • 我是如何在 Go 中构建 Web 服务的

    从用了近十年的 C# 转到 Go 是一个有趣的旅程。有时,我陶醉于 Go 的[简洁](https://www.youtube.com/watch?v=rFejpH_tAHM);也有些时候,当熟悉的 OOP (面向对象编程)[模式](https://en.wikipedia.org/wiki/Software_design_pattern)无法在 Go 代码中使用的时候会感到沮丧。幸运的是,我已经摸索出了一些写 HTTP 服务的模式,在我的团队中应用地很好。 当在公司项目上工作时,我倾向把可...

  • Golang 有多快?—— 对比 Go 和 Python 实现的 Eratosthenes 筛选法

    ![Photo by Max Duzij on Unsplash](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20200523-How-Fast-Is-Golang/Photo.jpeg) 时间宝贵,所以为什么浪费时间等待程序运行?除非过去几年与世隔绝,否则不会错过 Go 的兴起。由谷歌工程师 Robert Griesemer,Rob Pike 和 Ken Thompson [创造的](https:/...

  • 120
    Go:使用 Delve 和 Core Dump 调试代码

    ![由 Renee French 创作的原始 Go Gopher 为“ Go Go 之旅”创建的插图。](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20200523-Go-Debugging-with-Delve-and-Core-Dumps/Illustration.png) ℹ️ 这篇文章基于 Go Delve 1.4.1。 core dump 是一个包含着意外终止的程序其内存快照的文件。这个文...

  • 120
    Go:GOMAXPROCS 和实时更新

    ![由 Renee French 创作的原始 Go Gopher 作品,为“ Go 的旅程”创作的插图。](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20191210-Go-GOMAXPROCS-And-Live-Updates/1_Ct_BMGzFD4eKn6ztnR1iYA.png) ℹ️ 这篇文章基于 Go 1.13。 `GOMAXPROCS` 控制着同时执行代码的 OS 线程的最大数量。...

  • 120
    Go 中的模糊(Fuzz)测试

    ![由 Renee French 创作的原始 Go Gopher 作品,为“ Go 的旅程”创作的插图。](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20191025-Go-Fuzz-Testing-in-Go/Illustration.png) 模糊测试(Fuzzing)是一项使用随机数据加载我们程序的测试技术。是[对常规测试的补充](https://docs.google.com/document...

  • 120
    Go:并发以及调度器亲和

    ![由 Renee French 创作的原始 Go Gopher 作品,为“ Go 的旅程”创作的插图](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20200102-Go-Concurrency-And-Scheduler-Affinity/Illustration.png) 将 Goroutine 从一个 OS 线程切换到另一个线程需要一定开销,并且,如果这种操作过于频繁的话会降低应用性能。无论如何...

  • Go 高级基准测试

    ## 背景 有时你必须解决不同类型的问题。通常来说复杂的问题并不会只有单一的解决方案,但是解决方案的优劣取决于程序在运行时所要解决问题的子集。 我所遇到的一个例子是分析一些代理的连接中的某些数据流。 从流量中提取信息的方法主要有两种:保存整个数据流,当流量结束后立即分析;或者(使用一个缓存窗口)以降低速度为代价,在数据流传输过程中进行分析。 内存相对与处理能力来说要更加便宜,所以我的第一版解决方案是使用缓存的方案。 ### 第一版代码:使用缓存(buffer) ...

  • 120
    Go:g0,特殊的 Goroutine

    ![Illustration created for “A Journey With Go”, made from the original Go Gopher, created by Renee French.](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20200104-Go-g0-Special-Goroutine/cover.png) ℹ️ 这篇文章基于 Go 1.13。 在 Go 中创...

  • Go 切片的一种有趣内存泄漏方式

    今天我在看 Prashant Varanasi 的 Go 发布会演讲:[使用火焰图进行生产分析](https://www.youtube.com/watch?v=aAhNDgEZj_U)(Analyzing production using Flamegraphs),在演讲开始的第 28 分钟他提到了一种涉及切片的有趣且棘手的内存泄漏。为了自我提升,我将在这里写一下该内存泄漏的一种形式,并说明它是如何发生的。 首先,对于像 Go 这样的垃圾收集语言来说,**内存泄漏是保留了对对象的非预期引...

  • Go 运行时调度器处理系统调用的巧妙方式

    [goroutine](https://tour.golang.org/concurrency/1) 是 Go 的一个标志性特点,是被 Go 运行时所管理的轻量线程。Go 运行时使用[一个 M:N 工作窃取调度器](https://rakyll.org/scheduler/)实现 goroutine,将 Goroutine 复用在操作系统线程上。调度器有着特殊的术语用来描述三个重要的实体;G 是 goroutine,M 是 OS 线程(一个“机器 machine”),P 是“处理器(proces...

  • 120
    Go:内存管理分配

    ![Illustration created for “A Journey With Go”, made from the original Go Gopher, created by Renee French.](https://raw.githubusercontent.com/studygolang/gctt-images2/master/20191103-Go-Memory-Management-and-Allocation/cover.png) ℹ️ *这篇文章基于 Go 1.1...

  • 120
    Go:defer 语句如何工作

    ![Illustration created for “A Journey With Go”, made from the original Go Gopher, created by Renee French.](https://raw.githubusercontent.com/studygolang/gctt-images2/master/how-does-defer-statement-work/1.png) ℹ️ *这篇文章基于 Go 1.12。* [`defer` 语句]...

  • Go 中的动态作用域变量

    这是一个 API 设计的思想实验,它从典型的 Go 单元测试惯用形式开始: ```go func TestOpenFile(t *testing.T) { f, err := os.Open("notfound") if err != nil { t.Fatal(err) } // ... } ``` 这段代码有什么问题?断言 `if err != nil { ... ...

  • 为什么 Go 关心 unsafe.Pointer 和 uintptr 之间的差别

    Go 有两样东西或多或少是无类型指针的表示:uintptr 和 unsafe.Pointer (和外表相反,它们是内置类型)。 从表面上看这有点奇怪,因为 unsafe.Pointer 和 uintptr 可以彼此来回转换。为什么不只有一种指针表现形式?两者之间有什么区别? 表面的区别是可以对 uintptr 进行算数运算但不能对 unsafe.Pointer(或任何其他 Go 指针)进行运算。unsafe 包的文档指出了重要的区别: > uintptr 是整数,不是引用。将 Po...